Passing an instance variable to a form - rails
This is probably a bug due to my minimal understanding of Rails and the use of variables in different models, so if more code is required to answer this, or if my terminology is incorrect, please let me know and I will gladly update the question.
I have a feed of posts that I want the user to "like". Although the following code makes it like to work on a separate post page - site.com:3000/posts/*post.id*
- with form data being submitted like[liked_post_id]:*post.id*
, when I try to submit like this in a profile - site.com:3000/users/*user.id*
- which contains a post feed, form data is submitted like[liked_post_id]:
(empty)
How do I pass the id of a post in a post feed to a variable liked_post_id
in _like.html.erb
?
I noticed that the action is similarly shaped /likes
all over the board. Will this only work if you are on the page site.com:3000/posts/*post.id*
? I am wondering if I need to change it so that the form action is /posts/*post.id*/likes
when you are on the pagesite.com:3000/users/*user.id*
From my post:
#views/posts/_post.html.erb:
...
<%= render 'posts/like_form' if signed_in? %>
...
Go to the correct form:
#views/posts/_like_form.html.erb:
<div id="like_form">
<% if current_user.likes_this?(@post) %>
<%= render "posts/unlike" %>
<% else %>
<%= render "posts/like" %>
<% end %>
</div>
How from:
#views/posts/_like.html.erb
<%= form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :liked_post_id, :value => @post.id %>
<%= f.submit "Like" %>
<% end %>
From profile (message channel):
#views/users/show.html.erb
...
<%= render @posts %>
...
Loves the controller:
#controllers/likes_controller.rb
class LikesController < ApplicationController
before_filter :signed_in_user
def create
@post = Post.find(params[:like][:liked_post_id])
current_user.like!(@post)
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
end
...
User Model:
#models/user.rb
...
def like!(post)
likes.create!(liked_post_id: post.id)
end
...
@ frank-blizzard pointed out that my form markup is a problem. On the post page, the generated markup is:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" value="73" />
On the channel page:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" />
source to share
You can do something like this:
<% form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :post_id, :value => @post.id %>
<%= f.submit %>
<% end %>
The part current_user.likes.build(...)
should exit out of your view and inside your controller. You are using a method current_user.like!
, so I think you have already implemented some method in your custom model to accomplish this. If you haven't created your styling in the create
LikesController action where you can access the params[:like]
.
def create
@post = Post.find(params[:like][:post_id])
current_user.likes.build(@post)
# ...
end
EDIT
You might need to properly pass your @post variable into your _like_form parts, like this:
#views/posts/_post.html.erb:
...
<% if signed_in? %>
<%= render 'posts/like_form', :post => @post %>
<% end %>
...
This will give you the acceess variable post
inside the partial so that you can pre-populate your form's value with your id. See also these questions Pass variable to partial, rails 3? and be sure to read how to pass variables correctly. you can debug your views using<%= debug <variablename> %>
source to share