【问题标题】:Not sure why the VIEW does't work: Rails 4 nested attributes and has_many :through associaton in a form不知道为什么 VIEW 不起作用:Rails 4 nested attributes and has_many :through associaton in a form
【发布时间】:2015-10-12 13:13:43
【问题描述】:

我按照这个页面构建了我的应用程序:

Rails 4 nested attributes and has_many :through associaton in a form

但它在我的视图中没有显示任何内容:

(奇怪的是当我输入“f.fields_for :questionnaire_surveRys do |ff|”而不是正确的时,它显示了正确的页面。

任何建议将不胜感激。

这是我的模型:

问卷.rb

class Questionnaire < ActiveRecord::Base
    has_many :questionnaire_surveys
    has_many :surveys, through: :questionnaire_surveys
    accepts_nested_attributes_for :questionnaire_surveys
end

questionnaire_survey.rb

class QuestionnaireSurvey < ActiveRecord::Base
    belongs_to :questionnaire
    belongs_to :survey
    accepts_nested_attributes_for :survey
end

调查.rb

class Survey < ActiveRecord::Base
  has_many :questions, :dependent => :destroy
  accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true

  has_many :questionnaire_surveys
  has_many :questionnaires, through: :questionnaire_surveys

end

这是我的问卷调查表_controller.rb

def new
    @questionnaire = Questionnaire.new
    @surveys = Survey.all

end

def questionnaire_params
    params.require(:questionnaire).permit(:name, questionnaire_surveys_attributes: [:id, survey_attributes:[:id]])
end

这是我的 _form.html.erb

<%= form_for(@questionnaire) do |f| %>
  <p>
    <%= f.label :name %><br/>
    <%= f.text_field :name %>

    <div class="field">

     <%= f.fields_for :questionnaire_surveys do |ff| %>
       <%= ff.fields_for :survey do |builder| %>
         <% @surveys.each do |survey| %> 
          <%= builder.check_box :id, {}, survey.id %>
          <%= builder.label survey.name %>
         <% end %>
       <% end %>   
     <% end %>
   </div>

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

更新:

Started POST "/questionnaires" for ::1 at 2015-07-29 22:45:16 +0800
Processing by QuestionnairesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"k4SkRC08PwAHAo1iERmQCkssdQZYgf+uHwofPdeLbXo0O4/psY3Y7i/krQA01omToQ4VLlt/YQDNkcbpLGp86w==", "questionnaire"=>{"name"=>"what just happened", "questionnaire_surveys_attributes"=>{"0"=>{"survey_attributes"=>{"name"=>""}}}}, "commit"=>"Create Questionnaire"}
Unpermitted parameter: name
   (0.1ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "questionnaires" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "what just happened"], ["created_at", "2015-07-29 14:45:16.374246"], ["updated_at", "2015-07-29 14:45:16.374246"]]
  SQL (0.2ms)  INSERT INTO "surveys" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2015-07-29 14:45:16.377439"], ["updated_at", "2015-07-29 14:45:16.377439"]]
  SQL (0.1ms)  INSERT INTO "questionnaire_surveys" ("questionnaire_id", "survey_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["questionnaire_id", "52"], ["survey_id", "38"], ["created_at", "2015-07-29 14:45:16.378845"], ["updated_at", "2015-07-29 14:45:16.378845"]]
   (0.9ms)  commit transaction
Redirected to http://localhost:3000/questionnaires/52
Completed 302 Found in 12ms (ActiveRecord: 2.0ms)

更新 - 2015/7/31

Started POST "/questionnaires" for ::1 at 2015-07-31 17:46:50 +0800
Processing by QuestionnairesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"t/00prIClAUVdqPFxOnkTaxRPhTdY082PAvHb/VQSO4QQh8LLrNz6z2Qg6fhJv3URnNePN6d0ZjukB67DrFZfw==", "questionnaire"=>{"name"=>"OMG", "questionnaire_surveys_attributes"=>{"0"=>{"survey_attributes"=>{"name"=>""}}}}, "commit"=>"Create Questionnaire"}
   (0.2ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "questionnaires" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "OMG"], ["created_at", "2015-07-31 09:46:50.440466"], ["updated_at", "2015-07-31 09:46:50.440466"]]
  SQL (0.4ms)  INSERT INTO "surveys" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", ""], ["created_at", "2015-07-31 09:46:50.446176"], ["updated_at", "2015-07-31 09:46:50.446176"]]
  SQL (0.2ms)  INSERT INTO "questionnaire_surveys" ("questionnaire_id", "survey_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["questionnaire_id", "53"], ["survey_id", "39"], ["created_at", "2015-07-31 09:46:50.450001"], ["updated_at", "2015-07-31 09:46:50.450001"]]
   (0.9ms)  commit transaction
Redirected to http://localhost:3000/questionnaires/53
Completed 302 Found in 22ms (ActiveRecord: 2.4ms)

更新 - 2015/8/05

我不能在这里上传图片,希望这是你需要的:

<input placeholder="vision" type="text" name="questionnaire[questionnaire_surveys_attributes][0][survey_attributes][name]" id="questionnaire_questionnaire_surveys_attributes_0_survey_attributes_name">

更新 - 2015/8/11

_form.erb.html

 <div class="field">
         <% @surveys.each do |survey| %> 
            <%= check_box_tag "questionnaire[questionnaire_surveys_attributes][][survey_id]", survey.id %>
            <%= label_tag survey.name %>
         <% end %>
</div>

questionnaires_controller.rb

params.require(:questionnaire).permit(:name, questionnaire_surveys_attributes: [:survey_id])

def new
    @questionnaire = Questionnaire.new
    @surveys = Survey.all
end

更新 - 2015/8/17

我误用了has_many :throughaccepts_nested_attributes_for。 在has_many:xxx :through 的情况下,有xxx_ids。 在accepts_nested_attributes_for xxx 的情况下,有xxx_attributes

我在 questionnaire.rbquestionnaire_survey.rb 中都使用了 accepts_nested_attributes_for,这是一个错误。

做我想做的事的正确方法是只使用has_many :through。 然后我的questionnaire_controller.rb就会有

def questionnaire_params
    params.require(:questionnaire).permit(:name, :survey_id=>[])
end

在_form视图中应该是

 <%= check_box_tag "questionnaire[survey_id][]", survey.id %>

现在容易多了。

@Rich Peck 感谢您的帮助。

【问题讨论】:

  • 好的,谢谢你的参数!似乎正在为嵌套属性提交一些东西 - Unpermitted parameter: name。我强烈建议您将其添加到您的控制器并重试 - 我会更新我的答案
  • 请参阅更新 - 2015/7/31。而且我认为它行不通,因为它在参数中没有提交任何内容。我们可以尝试用 collection_check_boxes 代替 text_field。 1. &lt;%= builder.text_field :name, placeholder: survey.name %&gt; 2. &lt;%= survey.collection_check_boxes :survey_ids, @surveys, :id, :name %&gt; 两个代码都不起作用。
  • 它会起作用,我们会让它起作用。
  • 希望如此,我这边没有发现,你有什么新的建议吗?
  • 好的,仍然说您正在提交嵌套属性,这意味着表单要么被隐藏,要么其他原因阻止它加载:"questionnaire"=&gt;{"name"=&gt;"OMG", "questionnaire_surveys_attributes"=&gt;{"0"=&gt;{"survey_attributes"=&gt;{"name"=&gt;""}}}}。您可以进入您的表单,右键单击,选择inspect element 并将屏幕截图发送给我吗?这将显示表单是否实际具有元素。考虑到正在发送的参数,它应该有。

标签: ruby-on-rails-4 rails-activerecord nested-forms has-many-through strong-parameters


【解决方案1】:

首要任务 - 如果您没有看到表单元素出现,那是因为您没有在后端正确设置它。

很长一段时间以来,我一直在尝试设置它,但对于嵌入的表单不会出现感到非常沮丧。直到我正确地整理它,它才起作用。它被称为graceful degradation(我认为)-不会出现错误,但功能会受到影响。


首先,我认为您还没有在控制器中构建关联对象:

#app/controllers/questionnaire_controller.rb
def new
    @questionnaire = Questionnaire.new

    # You need to build the associated objects, like this:
    @questionnaire.questionnaire_surveys.build.build_survey

    @surveys = Survey.all

end

--

其次,有一种更好的方法可以显示 @surveys 对象的复选框:

<%= ff.fields_for :survey do |survey| %>
    <%= survey.collection_check_boxes :survey_ids, @surveys, :id, :name %>
<% end %>

你可以阅读collection_check_boxes here

--

第三,你绝对应该learn haml。你可以这样写你的整个表单:

= form_for @questionnaire do |f|

    .name
      = f.label :name 
      = f.text_field :name

    .field
      = f.fields_for :questionnaire_surveys do |ff| %>
         = ff.fields_for :survey do |survey| %>
           = survey.collection_check_boxes :survey_ids, @surveys, :id, :name

    .actions
      = f.submit

--

最后,不要使用 HTML 元素作为样式。

&lt;p&gt; & &lt;br&gt; should only be used as markup。如果您将它们用于样式效果,最终会导致浏览器兼容性等问题。

您需要让您的 CSS 进行样式设置(颜色、大小、位置)以及用作分隔应用程序内容的任何页面元素。


更新

好的,我查看了您的 BitBucket:

  1. 您需要在app/controllers/questionnaires_controller.rb#20 中取消注释@questionnaire.questionnaire_surveys.build.build_survey

如果你这样做,它应该可以工作。

我看不出模型和控制器的构造有任何问题。你确定你已经刷新等了吗?

我看到您正在调用&lt;%= render "form" %&gt; - 尝试将表单直接放在new 视图中以测试它是否有效。

另外,您是否尝试过使用简单的方法来添加额外的字段,如下所示:

   <%= f.fields_for :questionnaire_surveys do |ff| %>
       <%= ff.fields_for :survey do |builder| %>
         <% @surveys.each do |survey| %> 
           <%= builder.text_field :name, placeholder: survey.name %>
       <% end %>
   <% end %>

最后,如果您在表单提交后发布您发布的参数,我将更有能力查看您可能遇到的任何错误/问题。

--

您可以将参数更改为以下内容:

#app/controllers/questionnaires_controller.rb
...
def questionnaire_params
 params.require(:questionnaire).permit(:name, questionnaire_surveys_attributes: [:id, survey_attributes:[:name]])
end

【讨论】:

  • 感谢您的回复,但是,它似乎不适用于我的情况。故事是我先建立了调查,然后我想将调查与问卷相关联。据我的朋友说,我这样做是错误的,因为我尝试同时构建和关联它们。
  • 你是对的“如果你没有看到表单元素出现,那是因为你没有在后端正确设置它。”当我调用 ,因为 :questionnaire_surveys 中没有任何内容。我在想它 (@questionnaire.questionnaire_surveys.build.build_survey) 可能有效,但它仍然什么也没显示。
  • 我朋友的建议是:&lt;div class="field"&gt;&lt;% @surveys.each do |survey| %&gt;&lt;%= check_box_tag "questionnaire[questionnaire_surveys_attributes][][survey_id]", survey.id %&gt;&lt;%= label_tag survey.name %&gt;&lt;% end %&gt;&lt;/div&gt;
  • 如果您在控制器中构建了对象,则不需要任何这些。
  • 你能发布你的代码的 github repo 吗?模型中可能还有其他问题!
猜你喜欢
  • 2015-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多