Построение ActiveRecord для вложенного ресурса - PullRequest
1 голос
/ 12 июля 2011

(ПРИМЕЧАНИЕ. Исходный код здесь https://github.com/cthielen/dss-evote)

У меня есть простое приложение для голосования. Опрос - это набор вопросов для голосования, избирательный бюллетень - это экземпляр его предпочтений для каждого пользователя, а предпочтения бюллетеня has_many, которые, опять же, являются уникальными для каждого пользователя. Вот моделирование:

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

rout.rb имеет только это: ресурсы: опросы делают ресурсы: бюллетени конец

/ опросы / 1, кажется, работает, даже / опросы / 1 / бюллетени. / опросы / 1 / бюллетени / новые, где я сталкиваюсь с проблемами:

в balts_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

(соответствующий вид)

<%= 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 %>

Приводит к ошибке:

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 %>

Теперь, похоже, вместо правильных экземпляров класса формируется массив, но я не знаю, как это исправить.

РЕДАКТИРОВАТЬ: я должен упомянуть причину, по которой я пытаюсь создать @ ballot.preferences, заключается в том, что предпочтения представляют собой ответ человека, а длина предпочтений может изменяться от опроса к опросу. Поэтому, если в опросе шесть вопросов, @ ballot.survey.questions.length будет равно 6, и мне нужно создать 6 пустых @ ballot.preferences, которые затем будут представлены в форме form_for и, как мы надеемся, сохранены должным образом с помощью RESTful Create.

Заранее благодарим за любую помощь, которую вы можете предложить!

1 Ответ

1 голос
/ 12 июля 2011

Хорошо, это связано с этой строкой:

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

Поскольку сопоставление создает массив, который не может использоваться form_helper (ожидается, что имя модели обычно предоставляется связью ActiveRecord).

Вы должны придерживаться чего-то вроде:

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

Sidenote:

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

должно быть:

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