不确定为什么 VIEW 不起作用:Rails 4 个嵌套属性和 has_many :through associon in a form
Not sure why the VIEW does't work: Rails 4 nested attributes and has_many :through associaton in a form
我按照此页面构建了我的应用程序:
Rails 4 nested attributes and has_many :through associaton in a form
但它在我的视图中什么也没有显示:
(奇怪的是,当我输入 "f.fields_for :questionnaire_surveRys do |ff|" 而不是正确的那个时,它显示了正确的页面。
任何建议将不胜感激。
这是我的模特:
questionnaire.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
survey.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
这是我的 questionnaire_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 :through
和 accepts_nested_attributes_for
。
在 has_many:xxx :through
的情况下,有 xxx_ids
。
在 accepts_nested_attributes_for xxx
的情况下,有 xxx_attributes
。
我在 questionnaire.rb
和 questionnaire_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 感谢您的帮助。
要事第一 - 如果您没有看到表单元素出现,那是因为您没有在后端正确设置它。
很长一段时间以来,我都尝试设置它,但因为嵌入的表单不会出现而感到非常沮丧。直到我正确地整理出来它才起作用。它被称为 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 元素作为样式。
<p>
& <br>
should only be used as markup。如果您将它们用于样式效果,最终会导致浏览器兼容性等问题。
您需要让 CSS 进行样式设置(颜色、大小、位置),以及用作分隔应用程序内容的任何页面元素。
更新
好的,我查看了您的 BitBucket:
- 您需要在
app/controllers/questionnaires_controller.rb#20
中取消注释 @questionnaire.questionnaire_surveys.build.build_survey
如果你这样做,它应该会起作用。
我看不出模型和控制器的构造有任何问题。你确定你刷新了等吗?
我看到您正在调用 <%= render "form" %>
- 尝试将表单直接放入 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 %>
最后,如果您在提交表单后 post 您的 posted 参数,我将更有能力查看您可能拥有的任何 errors/problems。
--
您可以将参数更改为以下内容:
#app/controllers/questionnaires_controller.rb
...
def questionnaire_params
params.require(:questionnaire).permit(:name, questionnaire_surveys_attributes: [:id, survey_attributes:[:name]])
end
我按照此页面构建了我的应用程序:
Rails 4 nested attributes and has_many :through associaton in a form
但它在我的视图中什么也没有显示:
(奇怪的是,当我输入 "f.fields_for :questionnaire_surveRys do |ff|" 而不是正确的那个时,它显示了正确的页面。
任何建议将不胜感激。
这是我的模特:
questionnaire.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
survey.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
这是我的 questionnaire_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 :through
和 accepts_nested_attributes_for
。
在 has_many:xxx :through
的情况下,有 xxx_ids
。
在 accepts_nested_attributes_for xxx
的情况下,有 xxx_attributes
。
我在 questionnaire.rb
和 questionnaire_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 感谢您的帮助。
要事第一 - 如果您没有看到表单元素出现,那是因为您没有在后端正确设置它。
很长一段时间以来,我都尝试设置它,但因为嵌入的表单不会出现而感到非常沮丧。直到我正确地整理出来它才起作用。它被称为 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 元素作为样式。
<p>
& <br>
should only be used as markup。如果您将它们用于样式效果,最终会导致浏览器兼容性等问题。
您需要让 CSS 进行样式设置(颜色、大小、位置),以及用作分隔应用程序内容的任何页面元素。
更新
好的,我查看了您的 BitBucket:
- 您需要在
app/controllers/questionnaires_controller.rb#20
中取消注释
@questionnaire.questionnaire_surveys.build.build_survey
如果你这样做,它应该会起作用。
我看不出模型和控制器的构造有任何问题。你确定你刷新了等吗?
我看到您正在调用 <%= render "form" %>
- 尝试将表单直接放入 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 %>
最后,如果您在提交表单后 post 您的 posted 参数,我将更有能力查看您可能拥有的任何 errors/problems。
--
您可以将参数更改为以下内容:
#app/controllers/questionnaires_controller.rb
...
def questionnaire_params
params.require(:questionnaire).permit(:name, questionnaire_surveys_attributes: [:id, survey_attributes:[:name]])
end