I'm having problems implementing a kind of comments form, where comments (called "microposts") belong_to both users and posts, users have_many comments, and posts (called "propositions") have_many comments.
My code for the comments form is:
<%= form_for @micropost do |f| %>
<div class="field">
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
The MicropostsController has this in the create action:
def create
@proposition = Proposition.find(params[:proposition_id])
@micropost = current_user.microposts.build(params[:micropost])
@micropost.proposition = @proposition
if @micropost.save
flash[:success] = "Contribution submitted"
redirect_to root_path
else
@feed_items = []
render 'pages/home'
end
end
The form for creating a new micropost is on the same page as a proposition, yet the proposition id doesn't seem to get passed at any point.
This is the error I get on submitting the micropost form:
ActiveRecord::RecordNotFound in MicropostsController#create
Couldn't find Proposition without an ID
Parameters are:
{"commit"=>"Submit", "micropost"=>{"proposition_id"=>"", "content"=>"First comment"}, "authenticity_token"=>"TD6kZaHv3CPWM7xLzibEbaLJHI0Uw43H+pq88HLZFjc=", "utf8"=>"✓"}
I'm completely new to rails and very new to coding anything at all, so I'd be grateful for any help you can give me!
Thanks in advance.
Your params are:
"micropost"=>{"proposition_id"=>"", "content"=>"First comment"}
So to get proposition_id
, you have to do :
params[:micropost][:proposition_id]
But this is empty. And there is nowhere else to get this id
, that's why this line retrieves nil
:
@proposition = Proposition.find(params[:proposition_id])
Making this fail:
@micropost.proposition = @proposition
You must either:
add the proposition_id
as an hidden_field
store it in session
But I don't know your context enough to give you the proper solution here.
EDIT:
In your link, replace:
<%= f.hidden_field :proposition_id %>
with:
<%= f.hidden_field :proposition_id, :value => @proposition.id %>
If it doesn't work, show your params.
Note: it's bad practice to rely on instance variables, you should send local variable to each partial
As you can see, the proposition_id
parameter is empty, so your controller can't find the proposition unless you give it a valid id.
You need to make sure your new
form sends the proposition_id
attribute. One way to do this is:
Set the proposition in the new
action in the controller: @micropost.proposition = ...
In the form, add a hidden field for the id: f.hidden_field :proposition_id
In the create
action, find the appropriate Proposition with params[:micropost][:proposition_id]
(You'll also want to make sure to use attr_accessible
in your Micropost model, and make sure proposition_id
is NOT in that list. Otherwise, you'll be open to nasty security holes. See http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/ and Which fields should be protected from mass assignment?)
EDIT (due to comment):
Your new action should be like this:
def new
@micropost = Micropost.new
@micropost.proposition_id = params[:proposition_id]
This is slightly different from what is said above, and is due to the fact you're sending the proposition id in the request to new
. There's no need to look up the actual proposition record, since we're only interested in the id
field (which we already have).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With