I created a form to add a record to :vote
model that belongs to :article
model. As you can see below, the form to create the :vote
record is in a :article
view. In not using nested routes for these models so instead of using the form_for
helper, I'm using plain form_tags
. My problem is that strong_parameters
is not allowing my hidden field through.
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Body:</strong>
<%= @article.body %>
</p>
<p>
<strong>User:</strong>
<%= @article.user_id %>
</p>
<%= form_tag("/vote/#{@article.id}", method: :post) do -%>
<%= hidden_field_tag 'vote[value]', 1 %>
<%= submit_tag 'Up vote' %>
<% end -%>
<%= link_to 'Edit', edit_article_path(@article) %>
<%= link_to 'Back', articles_path %>
As you can see in the controller code, I have white listed the the param and the log data show the post body coming in the right format for the parameters hash but it won't reach my create action.
class VotesController < ApplicationController
def create
@article = Article.find(params[:id])
@vote = Vote.new(params[:strong_vote])
@vote.user_id = current_user.id
@vote.article_id = @article.id
@vote.save
redirect_to @article
end
private
def strong_vote
params.require(:vote).permit(:value)
end
end
Processing by VotesController#create as HTML Parameters:{"utf8"=>"✓","authenticity_token"=>"Y6eBxpwGXGdT2toeUrxAlLW58Hj8Eux+SvoWeVUoYa8=","vote"=>{"value"=>"1"}, "commit"=>"Up vote","id"=>"7"}
Article Load (0.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT 1 [["id", 7]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE"users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Rendered text template (0.0ms)
Completed 200 OK in 7ms (Views: 1.0ms | ActiveRecord: 0.4ms)
Here are my routes in case they may be helpful.
devise_for :users
root 'articles#index'
resources :articles
post '/vote/:id' => 'votes#create'
Update: I tried your answer doz87 but I get the following error:
ArgumentError in VotesController#create
When assigning attributes, you must pass a hash as an argument.
Extracted source (around line #5):
3
4
5
6
7
8
def create
@article = Article.find(params[:id])
@vote = Vote.new(:strong_vote)
@vote.user_id = current_user.id
@vote.article_id = @article.id
@vote.save
Rails.root: /home/w/Folders/playground/ruby/voter
Application Trace | Framework Trace | Full Trace
app/controllers/votes_controller.rb:5:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"AVKHgcsOwQhwWJGfSGQhIL1Lbr7yhSRaGKTrxuLcAuo=",
"vote"=>{"value"=>"1"},
"commit"=>"Up vote",
"id"=>"7"}
The reason this isn't working is because your not assigning anything to the new Vote. Params[:strong_vote] doesn't exist
You should write it like this:
Also it's good practice to catch any errors from a failed save. You should wrap @vote.save in an if block incase something goes wrong.