我有以下路线:
shallow do
resources :countries do
resources :airports
end
end
我在调用两条路线方面遇到了麻烦。
airports_controller.rb
文件开始
def create
Rails::logger.debug "!!! Building airport with parameters #{params}"
@country = Country.find(params[:country_id])
Rails::logger.debug "!!! Found airport #{@country.name}"
@airport = @country.airports.build(params[:airport])
最后一行给出了错误Minitest::UnexpectedError: ActiveModel::ForbiddenAttributesError: ActiveModel::ForbiddenAttributesError
,但我打电话给的参数是
!!! Building airport with parameters {"airport"=>{"iata_code"=>"CCC",
"icao_code"=>"CCCC", "name"=>"Airport 3", "city"=>"City 3", "latitude"=>"1.5",
"longitude"=>"1.5"}, "country_id"=>"980190962", "controller"=>"airports",
"action"=>"create"}
据我所知,所有这些都在我允许的参数范围内:
def airport_params
params.require(:airport).permit(:iata_code, :icao_code, :name, :city, :latitude, :longitude, :notes, :country_id)
end
其次,我的airports\_form.html.erb
开始<%= form_for [@country, @airport] do |f| %>
,但这会产生错误Minitest::UnexpectedError: ActionView::Template::Error: undefined method 'airports_path' for #<#<Class:0x4b0ba30>:0x55a2e48>
。是的,该路径未定义,但我试图进入路径country_airports_path
, 已定义。
那我在这里错过了什么?
答案 0 :(得分:0)
在&#34; def create&#34;
def create
...
@airport = @country.airports.build(airport_params)
您已正确创建了&#34; airport_params&#34;功能,但是你没有调用它。这应该解释ForbiddenAttributesError
。
对于未定义的方法,乍一看它看起来像是一个错误的关联,你的模型是否正确相关(即belongs_to
和has_many
)?如果是,您可以尝试将url: country_airports_path
添加到form_for
字段。
答案 1 :(得分:0)
<强>属性强>
您收到的属性错误主要是由于您未使用strong_params
。
Rails 4引入了strong_params
,使您能够定义要传递给模型的特定属性(防止批量分配)。您遇到的问题是您正在使用Rails 3
方式 - 传递所有属性而不将它们列入白名单
正如所指出的,你最好这样做:
#app/controllers/airports_controller.rb
Class AirportsController < ApplicationController
def create
@airport = Airport.new(airport_params)
end
private
def airport_params
params.permit(:airport).permit(:your, :params).merge(country_id: params[:country_id])
end
end
但是,我相信你需要考虑更深层次的东西。
您目前正在使用.build
作为机场模型对象。虽然没有什么错误,但你需要考虑你想要实现的 ......
Airport
模型对象是一个独立的对象。您可以轻松地将其与Country
模型相关联,方法是在强大的参数中设置foreign_key
(如上所示)
如果你使用这一行:@airport = @country.airports.build
,那么你正在使用Country
对象,IMO会自行打开这个对象。如上所述,你所做的事情并没有“错误”;只是我要么直接使用机场模型(如上所述),要么使用accepts_nested_attributes_for
来处理Country
模型
-
<强>路线强>
其次,您的路径错误将由您的form_for
form_for
从ActiveRecord对象构建一个表单 - 它通过使用诸如model_name
之类的参数来构建表单的“url”/“action”。
这意味着每次使用ActiveRecord对象(变量)填充form_for
对象时,Rails将根据您传递的内容构建路径(它不知道对象是否嵌套)< / p>
<%= form_for @airport do |f| %>
# builds route using "airport_path"
<% end %>
如果你想创建一个嵌套的表单,你可以更好地使用一个ActiveRecord对象数组,以便为Rails提供你正在使用嵌套的知识资源:
<%= form_for [@country, @airport] do |f| %>
# builds route using "country_airport_path"
<% end %>