Reputation: 133
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 %>
Upvotes: 0
Views: 751
Reputation: 21775
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:
resources :jobs do
resources :bids
end
= form_for @job, @bid ...
As in first time you don't have @job, you can use:
= form_for :job, @bid
Upvotes: 1
Reputation: 442
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.
Upvotes: 1
Reputation: 3144
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
Upvotes: 0