Members create votes that both belong to them and to another model, Issues. Currently I'm doing this with a hidden form and passing the appropriate parameters. Here's the code on the issues index view:
<%= form_for(@vote) do |f| %>
<%= f.hidden_field "issue_id", :value => issue.id %>
<%= f.hidden_field "member_id", :value => session[:member_id] %>
<%= f.hidden_field "type", :value => :Upvote %>
<%= f.label issue.upvotes_count(issue.id) %>
<%= submit_tag "Up", :class => 'up-vote' %>
<% end %>
This doesn't seem ideal as it leaves issue_id and member_id open to mass assignment. Is there a better way to do this with a button_to tag or something?
Here's the controller code:
class VotesController < ApplicationController
#GET
def new
@vote = Vote.new
end
# POST
def create
@vote = Vote.new(params[:vote])
@vote.member_id = current_member
if @vote.save
redirect_to issues_path
else
redirect_to issues_path, notice: "you must be logged in to vote"
end
end
end
and
class IssuesController < ApplicationController
# GET
def index
@issues = Issue.find(:all)
@vote = Vote.new
end
# GET
def show
@issue = Issue.find(params[:id])
respond_to do |format|
format.html
format.js
end
end
end
Use scope in the controller:
@issue = Issue.find(params[:issue_id])
@vote = @issue.votes.new(params[:vote])
@vote.save
and do not pass member_id and issue_id to hidden fields.
If you have proper nested RESTful routes you should be able to get params[:issue_id] directly.