开发者

ActiveRecord building for nested resource

开发者 https://www.devze.com 2023-03-19 06:58 出处:网络
(NOTE: Source code here https://github.com/cthielen/dss-evote) I\'ve got a simple voting application. A survey is the set of questions to vote on, a ballot is a per-user instance of their preferences

(NOTE: Source code here https://github.com/cthielen/dss-evote)

I've got a simple voting application. A survey is the set of questions to vote on, a ballot is a per-user instance of their preferences, and the ballot has_many preferences, which again, are unique to each user. Here's the modeling:

class Ballot < ActiveRecord::Base
  belongs_to :survey
  has_many :preferences
end

class Survey < ActiveRecord::Base
  has_many :questions
  has_many :eligibilities
  has_many :ballots

  accepts_nested_attributes_for :questions, :allow_destroy => true

  attr_accessible :title, :description, :status, :deadline, :questions_attributes

  def owner
    Person.find(owner_id)
  end
end

class Question < ActiveRecord::Base
  belongs_to :survey
  has_many :preferences
end

class Preference < ActiveRecord::Base
  belongs_to :ballot
  belongs_to :question
end

routes.rb only has this: resources :surveys do resources :ballots end

/surveys/1 seems to work, even /surveys/1/ballots. /surveys/1/ballots/开发者_JAVA百科new is where I run into issues:

in ballots_controller.rb:

def new
  @survey = Survey.find(params[:survey_id])

  @ballot = @survey.ballots.build

  @survey.questions.count.times { @ballot.preferences.build }

  respond_to do |format|
    format.html # new.html.erb
  end
end

(corresponding view)

<%= form_for [@survey, @ballot] do |f| %>
  <%= f.fields_for @ballot.preferences do |preferences_fields| %>
    <% for question in @preferences_fields %>
      <p>
    <%= f.label question.question %>
    <%= radio_button(question.id, "preference", "Yes") %> Yes
    <%= radio_button(question.id, "preference", "No") %> No
    <%= radio_button(question.id, "preference", "Decline") %> Decline
  </p>
    <% end %>
  <% end %>

  <div class="actions">
    <%= f.submit "Vote" %>
  </div>
<% end %>

Results in the error:

NoMethodError in Ballots#new

Showing /Users/cthielen/Projects/Work/dss-evote/app/views/ballots/_form.html.erb where line #2 raised:

undefined method `model_name' for Array:Class
Extracted source (around line #2):

1: <%= form_for [@survey, @ballot] do |f| %>
2:   <% f.fields_for @ballot.preferences do |preferences_fields| %>
3:     <% for question in @preferences_fields %>
4:       <p>
5:      <%= f.label question.question %>

Now, it appears an array is being formed instead of proper instances of the class, but I'm at a loss for how to properly fix this.

EDIT: I should mention the reason I'm attempting to build @ballot.preferences are that the preferences represent a person's answer, and the length of preferences may change from survey to survey. So if a survey has six questions, @ballot.survey.questions.length will be 6, and I need to create 6 blank @ballot.preferences, which will then be represented by form_for and hopefully saved properly using a RESTful Create.

Thanks in advance for any help you can offer!


Ok, this is due to this line:

@ballot.preferences = @survey.questions.map{|question| question.preferences.build}

Because the mapping creates an Array which could not be used by the form_helper (expecting a Model name generally provided by an ActiveRecord Relation).

You should stick to something like:

@survey.questions.count.times { @ballot.preferences.build }

Sidenote:

<% fields_for @ballot.preferences do |preferences_fields| %>

should be:

<%= f.fields_for :preferences do |preferences_field| %>
0

精彩评论

暂无评论...
验证码 换一张
取 消