In my Rails 3 application I have a simple model relationship which is as follows:
Animal Model
has_many :claims
Claim Model
belongs_to :animal
has_many :payments
Payments Model
belongs_to :claim
The claim table has a column called animal_id and the payments table has a column called claim_id.
I can successfully list all payments owned by a claim.
What I am trying to do is add a link within the animal show view that creates a new claim with the animal_id already set and the same with the claim show view for the new payment link.
From what I have read you can manually create a link_to with the controller and action set, like so:
Claim Show View
<%= link_to 'Create a Payment', {:controller => "payments", :action => "new", :claim_id => '@claim.id'} %>
This doesn't seem to work, although it does correctly link to the new payment page.
Is there a simpler way?
Off the top of my head, and untested, I think the following would work:
= link_to 'Create Payment', payments_path(:payment=>{:claim_id=>@claim.id}), :method => :post
Adding a hash inside the url helper is just going to put params on the url, which will be interpreted by rails the same way "normal" params posted from a form are.
This will be equivalent to submitting a new payment form, so it will redirect the same way that would. If you want it to be handled via ajax just add :remote => true
, and be sure your the create action on your PaymentsController responds to javascript correctly.
Update: Read your question again, you want the new payment form with the claim_id already set?
Ok, there are many ways you could do this. If you pass params to the new action you can take the claim_id from the params, the same as I showed above for creating a record:
= link_to 'New Payment', new_payment_path(:claim_id=>@claim.id)
This should link you to /payments/new?claim_id=123
Then in your controller:
def new
@payment = Payment.new(:claim_id => params[:claim_id])
end
However, as was pointed out in the comments, the better way to do this is to nest payments under claims:
In your routes:
resources :claims do
resources :payments
end
In your PaymentsController:
before_filter :load_claim
def new
@payment = @claim.payments.build
end
def create
@payment = @claim.payments.build(params[:payment])
...
end
private
def load_claim
@claim = Claim.find(params[:claim_id])
end
In your link:
= link_to 'New Payment', new_claim_payment_path(@claim)
Just be aware that now your payment path helpers will need claims in them, ie:
= link_to 'Payment', claim_payment_path(@claim, payment)
Same thing for form helpers:
= form_for [@claim, @payment] ...