表单中相同模型的多个实例 - 解析参数哈希

时间:2013-01-09 20:36:57

标签: ruby-on-rails

在大多数情况下,我无疑是一个真正的新手,包括形成和解析params哈希。我正在尝试从投票应用程序的表单中获取相同模型的实例的哈希值。用户可以根据等级投票选出尽可能多的候选人。

我的votes#new确实创建了Candidate.count个投票实例,user_idrank已正确设置。我知道这一点,因为表格正在为每个候选人正确地迭代@user.votes

以下是呈现形式的片段:

<input id="vote_rank" name="vote[rank]" type="hidden" value="1" />
<label for="vote_Candidate">Candidate</label>
<select id="vote_candidate_id" name="vote[candidate_id]"><option value=""></option>
<option value="1">Smithers</option>
<option value="2">Mr. Burns</option>
<option value="3">Bart</option>
<option value="4">Lionel Hutz</option>
<option value="5">Jimbo</option>
<option value="6">Troy McClure</option>
<option value="7">Duffman</option>
<option value="8">Maggie</option>
<option value="9">Moe</option>
<option value="10">Principal Skinner</option>
<option value="11">Apu Nahasapeemapetilan</option></select>

我无法弄清楚如何将表单从表单恢复到我的votes#create。我能够使用一组candidate_idrank值(最后一个)得到一个params哈希值,但不是所有11个实例都放在第一位。表单希望放弃正确的数据。

@user.votes.create(vote_params)中的{p> votes#create会抛出此错误:undefined method `stringify_keys' for "rank":String

以下是我的控制器方法和表格。

def new
  @user = current_user
  @votes = Candidate.count.times { |i| @user.votes.build(:rank => i + 1) }
end

def create
  @user = current_user
  #params[:user][:votes].each do |vote_params|
  #@user.votes.create(vote_params)
  params[:vote].each do |vote_params|
    @user.votes.create(vote_params)
  end
  respond_to do |format|
    if @user.valid?
      format.html { redirect_to @user, notice: 'votes were successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end



<%= form_for :votes, :url => votes_path do |f| %>
  <% @user.votes.each do |v| %>
    <%= fields_for v do |vote_fields| %>
      <%= vote_fields.hidden_field :rank %>
      <%= vote_fields.label "Candidate" %>
      <%= vote_fields.collection_select :candidate_id, Candidate.all, :id, :name, :include_blank => true %>
    <% end %>
  <% end %>
  <p><%= f.submit :class => 'medium radius button' %></p>
<% end %>

这是相关的HTML

只传递了一组值:

{"utf8"=>"✓", "authenticity_token"=>"bVLXCQtOffEtu5xBNI0e94o9j9mJ8alHhuBhDkkfaRA=", "vote"=>{"rank"=>"11", "candidate_id"=>""}, "commit"=>"Save Votes", "action"=>"create", "controller"=>"votes"}

虽然表单试图放弃正确的值:

vote[rank]:1
vote[candidate_id]:2
vote[rank]:2
vote[candidate_id]:4
vote[rank]:3
vote[candidate_id]:2
vote[rank]:4
vote[candidate_id]:9
etc. (up to 11!)

任何帮助表示感谢。

更新

解决了这个问题。我把它放在以防万一,因为我没有直接找到任何东西,我花了很长时间来解决这个问题。

我的表单正在创建具有相同名称的对象,这些对象只是被覆盖。解释为什么我只能将最后一组值放入数据库中。

我的表单现在迭代从votes#new传递的对象,并在名称中包含投票的排名。

<%= form_for :vote, :url => votes_path do |f| %>
  <% @user.votes.each do |v| %>
    <% if v.errors.any? %>
      <h1>errors</h1>
    <% end %>
  <%= f.fields_for "#{v.rank}" do |builder| %>
    <%= builder.hidden_field :rank, :value => v.rank %>
      <div class="row">
        <div class="one columns"><%= builder.label "Rank #{v.rank}", :class => "left inline" %></div>
      <div class="eleven columns"><%= builder.collection_select :candidate_id, Candidate.all, :id, :name, {:include_blank => true}, :class => "two" %></div>
      </div>
    <% end %>
  <% end %>
  <%= f.submit "Submit", :confirm => "Please review your ballot and confirm that your votes are correct before submitting. This message will appear as a reminder each time you press 'Submit', even if you've edited your ballot.", :class => "small round button" %>
<% end %>

这会产生一个params[:vote]散列的唯一命名哈希值,例如

{"1"=>{"rank"=>"1", "candidate_id"=>"5"}, "2"=>{"rank"=>"2", "candidate_id"=>"2"}, "3"=>{"rank"=>"3", "candidate_id"=>"7"}, "4"=>{"rank"=>"4", "candidate_id"=>"4"}, "5"=>{"rank"=>"5", "candidate_id"=>"10"}, "6"=>{"rank"=>"6", "candidate_id"=>""}, "7"=>{"rank"=>"7", "candidate_id"=>""}, "8"=>{"rank"=>"8", "candidate_id"=>""}, "9"=>{"rank"=>"9", "candidate_id"=>""}, "10"=>{"rank"=>"10", "candidate_id"=>""}, "11"=>{"rank"=>"11", "candidate_id"=>""}}

我的votes#create方法将由params哈希中的键/值对组成的数组转储到@user.votes.create(my_array)

def create
  @user = current_user
  @user.votes.create(sanitize_and_compress_vote_array params[:vote])
    redirect_to thankyou_path
end

接下来的挑战是让验证错误消息正常工作。这是我的头脑,因为我想要验证的是在任何值到达数据库之前candidate_id作用于user_id的唯一性的一组键值对。看起来Rails并不容易。

validates :candidate_id, :presence => true, :uniqueness => {:scope => :user_id, :message => "You may only vote for a candidate once."}

验证适用于拒绝重复值,但它没用,因为那些已经传递的值显然已经存在于数据库中。我没有发现如何在他们保存之前对自己的成员进行自我验证,并且我觉得我正在和自己说话: - (

0 个答案:

没有答案