我已经在这几个小时了,但无法理解:
尝试在新的组织表单中创建新地址。可以为组织,公司或员工创建地址。我希望与Orgainsation / Company / Employee相关的Address_id存储在他们的数据库记录中,但无法使strong_parameters正常工作。
模型/ organisation.rb
class Organisation < ActiveRecord::Base
belongs_to :address
has_many :users
accepts_nested_attributes_for :address
end
模型/ address.rb
class Address < ActiveRecord::Base
has_many :organisations
has_many :companies
has_many :employees
end
视图/组织/ _form.html.erb
<%= form_for(@organisation) do |f| %>
<% if @organisation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@organisation.errors.count, "error") %> prohibited this organisation from being saved:</h2>
<ul>
<% @organisation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%= f.fields_for @address do |t| %>
<div>
<%= t.label :Line_1 %><br />
<%= t.text_field :line1 %>
</div>
<div>
<%= t.label :Line_2 %><br />
<%= t.text_field :line2 %>
</div>
<div>
<%= t.label :Line_3 %><br />
<%= t.text_field :line3 %>
</div>
<div>
<%= t.label :Line_4 %><br />
<%= t.text_field :line4 %>
</div>
<div>
<%= t.label :Postcode %><br />
<%= t.text_field :postcode %>
</div>
<div>
<%= t.label :Country %><br />
<%= t.text_field :country %>
</div>
<% end %>
<div class="field">
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</div>
<div class="actions">
<%= f.submit %>
</div>
控制器/ organisations_controller.rb
class OrganisationsController < ApplicationController
espond_to :html, :json
before_action :set_organisation, only: [:show, :edit, :update, :destroy]
def new
@organisation = Organisation.new
@address = Address.new
respond_with(@organisation)
end
def create
puts "Start of debug"
puts organisation_params[:address_attributes]
puts "End of debug"
@organisation = Organisation.new(organisation_params)
@address = Address.new(organisation_params[:address_attributes])
@address.save
@organisation.address = @address.id
@organisation.save
respond_with(@organisation)
end
private
def set_organisation
@organisation = Organisation.find(params[:id])
end
def organisation_params
params.require(:organisation).permit(:name, :phone, :creator, :contact, :renewal, :approved, :balance, address_attributes:[:line1, :line2, :line3, :line4, :postcode, :country, :organisation_id])
end
end
但我不断收到以下错误:
Started POST "/organisations" for 127.0.0.1 at 2014-12-11 23:40:54 +0000
Processing by OrganisationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T2344536dhfjkhkj3eb5g43glwy547fy5p2nbydddfr=", "organisation"=>{"name"=>"The company", "address"=>{"line1"=>"1 The Road", "line2"=>"", "line3"=>"", "line4"=>"", "postcode"=>"", "country"=>"Ireland"}, "phone"=>"01111111"}, "commit"=>"Create Organisation"}
Start of debug
Unpermitted parameters: address
End of debug
Unpermitted parameters: address
Unpermitted parameters: address
(0.4ms) BEGIN
SQL (1.0ms) INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2014-12-11 23:40:54.404236"], ["updated_at", "2014-12-11 23:40:54.404236"]]
PG::NotNullViolation: ERROR: null value in column "line1" violates not-null constraint
DETAIL: Failing row contains (21, null, null, null, null, null, null, 2014-12-11 23:40:54.404236, 2014-12-11 23:40:54.404236).
: INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
(0.4ms) ROLLBACK
Completed 500 Internal Server Error in 7ms
ActiveRecord::StatementInvalid (PG::NotNullViolation: ERROR: null value in column "line1" violates not-null constraint
DETAIL: Failing row contains (21, null, null, null, null, null, null, 2014-12-11 23:40:54.404236, 2014-12-11 23:40:54.404236).
: INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"):
app/controllers/organisations_controller.rb:29:in `create'
在我看来,地址没有被创建,因为它无法访问传递的地址属性,但却是“未经许可的参数”。即使我将它包含在organisation_params.permit语句中????
我在这里做错了吗?
修改1
根据hkumar的建议,我已编辑views/organisations/_form.html.erb
文件,现在说<%= f.fields_for "#{@address}_attributes" do |t| %>
但错误现在看起来像:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T2344536dhfjkhkj3eb5g43glwy547fy5p2nbydddfr=", "organisation"=>{"name"=>"The company", "#<Address:0x00000003aa2690>_attributes"=>{"line1"=>"The Road", "line2"=>"", "line3"=>"", "line4"=>"", "postcode"=>"", "country"=>"Ireland"}, "phone"=>"01111111"}, "commit"=>"Create Organisation"}
Start of debug
Unpermitted parameters: #<Address:0x00000003aa2690>_attributes
End of debug
修改2
遵循Paul Richter的建议,现在错误是:
Started POST "/organisations" for 127.0.0.1 at 2014-12-12 01:35:13 +0000
Processing by OrganisationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"T2344536dhfjkhkj3eb5g43glwy547fy5p2nbydddfr=", "organisation"=>{"name"=>"The company", "address_attributes"=>{"line1"=>"The road", "line2"=>"", "line3"=>"", "line4"=>"", "postcode"=>"", "country"=>"Ireland"}, "phone"=>"01111111"}, "commit"=>"Create Organisation"}
Start of debug
{"name"=>"The company", "phone"=>"01111111", "address_attributes"=>{"line1"=>"The road", "line2"=>"", "line3"=>"", "line4"=>"", "postcode"=>"", "country"=>"Ireland"}}
End of debug
(0.6ms) BEGIN
SQL (0.9ms) INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2014-12-12 01:35:14.196724"], ["updated_at", "2014-12-12 01:35:14.196724"]]
PG::NotNullViolation: ERROR: null value in column "line1" violates not-null constraint
DETAIL: Failing row contains (46, null, null, null, null, null, null, 2014-12-12 01:35:14.196724, 2014-12-12 01:35:14.196724).
: INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
(0.3ms) ROLLBACK
Completed 500 Internal Server Error in 57ms
ActiveRecord::StatementInvalid (PG::NotNullViolation: ERROR: null value in column "line1" violates not-null constraint
DETAIL: Failing row contains (46, null, null, null, null, null, null, 2014-12-12 01:35:14.196724, 2014-12-12 01:35:14.196724).
: INSERT INTO "addresses" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"):
app/controllers/organisations_controller.rb:29:in `create'
最终修改
感谢Paul Richter,以下代码现在可以使用(对于任何偶然发现它的人):
controllers / organisations_controller.rb
class OrganisationsController < ApplicationController
espond_to :html, :json
before_action :set_organisation, only: [:show, :edit, :update, :destroy]
def new
@organisation = Organisation.new
@organisation.build_address
end
def create
@organisation = Organisation.new(organisation_params)
@organisation.save
respond_with(@organisation)
end
private
def set_organisation
@organisation = Organisation.find(params[:id])
end
def organisation_params
params.require(:organisation).permit(:name, :phone, :creator, :contact, :renewal, :approved, :balance, address_attributes:[:line1, :line2, :line3, :line4, :postcode, :country, :organisation_id])
end
end
答案 0 :(得分:2)
该问题涉及以下形式的这一行:
f.fields_for @address do |t|
控制器中的这一行(显示完整的方法,所以我们都在同一页面上):
def new
@organisation = Organisation.new
@address = Address.new # This line, specifically
respond_with(@organisation)
end
问题在于,您创建单独的Address
和Organization
对象,就好像它们是独立的独立实体一样,但是从Address
belongs_to
Organization
开始(根据您的模型,Address
实际上取决于父Organization
,因此应该正确关联。
相反,您可能希望这样做:
def new
@organisation = Organisation.new
@organization.build_address
...
这将设置一个与其父Address
相关联的新Organization
对象。
然后在表单中,将fields_for
行更改为:
f.fields_for :address do |t|
这将调用address
对象的@organization
方法,[insert 1 magic}将使用accepts_nested_attributes_for
的命名约定。
简而言之,您看到错误的原因是,虽然您确实正确设置了强参数,但是将一个单独的,已断开连接的Address
对象传递给f.fields_for
阻止表单字段被正确命名。
修改强>
现在表单已正确设置,请将create
方法更改为:
def create
@organisation = Organisation.new(organisation_params)
@organisation.save
respond_with(@organisation)
end
在下面的评论中,您提到如何获取我正在创建的地址的ID并将其存储在组织中。需要说明的是,此时地址没有id
,但由于您在accepts_nested_attributes_for :address
模型中设置了Organization
行,因此Rails会创建一个新{{1}通过使用您传入的Address
哈希中的Organization
参数,已将对象与address_attributes
相关联。
这一行(organization_params
)为您创建整个结构,只要这些参数符合预期的命名约定即可。(/ p>