简体   繁体   中英

Rails 3 Saving with Multiple Associations

I am building a Rails 3 app with a job board, where workers can submit bids for jobs. I have the following associations:

Job:
  has_many :bids
  has_many :workers, :through => :bid

Bid:
  belongs_to :job
  belongs_to :worker

Worker:
  has_many :bids
  has_many :jobs, :through => :bid

I have a form on the Show Job Page in which workers can submit bids. In the controllers, I have the following:

Job Controller:
  def show
    @bid = current_worker.bids.build
  end   

Bid Controller:
  def create
    @bid = current_worker.bids.build(params[:bid])
    @bid.save
  end

With the code above, a submitted bid will not save correctly because it is missing the job_id:

1) What is the correct way to save the bid with BOTH the job_id and worker_id?

2) (I am having trouble passing the job_id from the Job Controller show method to the Bid Controller create method) - is it secure to pass the job_id in a sessions variable?

For reference, the bid form looks like:

<%= form_for(@bid) do |f| %>

  <%= f.label :min_price, "Minimum Price" %>
  <%= f.text_field :min_price %>

  <%= f.label :fee %>
  <%= f.text_field :fee %>

  <%= f.label :comments %>
  <%= f.text_area :comments, placeholder: "Comments..." %>
  <%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>

Code depends on what safety you want, I suppose you want to have to protected jobs which current_worker can't make bids to, so you need that does not seems to depend on bid, instead in job.

As you are first creating a bid you can pass job_id, in the form or as part of the route.

If you want to deny a worker to bid to any job you could do something like this:

Bids Controller:

  def create
    job = Job.find(params[:job_id])
    if current_worker.can_bid? job
      @bid = current_worker.bids.build params[:bid]
    else
      # handle unauthorised bidding

In worker model, this is just an example:

def can_bid?(job)
  # Implement code here
  # example:
  # job.public? or invited_to?(job)
end

# example of invited_to?(job)
def invited_to?(job)
  job.invitees.include? self
end

I am not sure if this answers your question.

I think you could use this to pass job id in route:

Routes

resources :jobs do
  resources :bids
end

View

= form_for @job, @bid ...

As in first time you don't have @job, you can use:

= form_for :job, @bid

I'm a rails newbie but I think instead of saying

<%= form_for(@bid) do |f| %>

try

<%= form_for(@job, @bid) do |f| %>

then in your bid controller new action do something like this

def new
  @job = Job.find(params[:job_id])
  @bid = @job.bids.build
end

and then in your routes you should nest the bid under the job resources like

resources :jobs do
  resources :bids
end

that should do it I hope, like I said I'm a newbie and may be wrong on this.

Just check your model Bid. Its belogs to two models. So You have to make it as polymorphic table. Re Structure your models as follows

Bid:
  belongs_to :bidable, polymorphic: true

Job:
  has_many :workers, :through => :bid
  has_many :bids, :as => :bidable

Worker:
  has_many :bids, :as => :bidable
  has_many :jobs, :through => :bid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM