Search code examples
ruby-on-railsmass-assignment

Is there a way to do this in Rails without mass assignment?


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

Solution

  • 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.