在 Rails 中使用 fields_for 4...不保存新字段
Using fields_for in Rails 4...does not save the new fields
我正在尝试对我正在处理的项目使用 fields_for 辅助方法。原始表格可以正常工作并保存。新属性不保存,我得到一个 NoMethodError 和一个未定义的方法。我错过了什么?!
这是我的列表模型:
class Listing < ActiveRecord::Base
has_one :listing_commerical_attribute
accepts_nested_attributes_for :listing_commerical_attribute, :allow_destroy => true
这是我的 listing_commercial_attribute 模型:
class ListingCommercialAttribute < ActiveRecord::Base
belongs_to :listing
accepts_nested_attributes_for :listing
end
这是我的控制器:
def new
@listing.build_listing_commercial_attribute
respond_to do |format|
format.html # new.html.erb
format.json { render json: @listing }
end
end
private
def commercial_params
params.require(:commerical_listing_attribute)
.permit(:gas_pipe_size,
:amperage,
:basement_ceiling_height,
:ceiling_height,
:door_size,
:zoning,
:previous_use,
:community_board,
:delivery_date,
:key_money,
:security_deposit,
:price_per_sq_ft,
:did_size)
end
这是我的 _form.html.erb:
<h2 class="text-center">Commercial</h2>
<%= f.fields_for :listing_commerical_attributes do |ff| %>
<div class="field">
<%= ff.label :gas_pipe_size, "Gas Pipe Size", class: "general-text-label" %>
<%= ff.number_field :gas_pipe_size, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :amperage, "Amperage", class: "general-text-label" %>
<%= ff.number_field :amperage, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :ceiling_height, "Ceiling Height", class: "general-text-label" %>
<%= ff.number_field :ceiling_height, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :basement_ceiling_height, "Basement Ceiling Height", class: "general-text-label" %>
<%= ff.number_field :basement_ceiling_height, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :door_size, "Door Size", class: "general-text-label" %>
<%= ff.number_field :door_size, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :zoning, "Zoning", class: "general-text-label" %>
<%= ff.text_field :zoning, class: "general-text-field" %>
</div>
<div class="field">
<label for="tenant_improvements" class="general-text-label">Tenant Improvements <small>(If Applicable)</small></label>
<%= ff.text_area :tenant_improvements, :rows => "4", class: "general-text-area" %>
</div>
<div class="field">
<label for="previous_use" class="general-text-label">Previous Use <small>(If Applicable)</small></label>
<%= ff.text_area :previous_use, :rows => "4", class: "general-text-area" %>
</div>
<div class= "field">
<%= ff.label :community_board, "Community Board", class: "general-text-label" %>
<%= ff.text_field :community_board, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :delivery_date, "Delivery Date", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-calendar"></i></span>
<%= ff.text_field :delivery_date, :class => "datepicker general-text-field" %>
</div>
<div class="field">
<%= ff.label :key_money, "Key Money", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :key_money, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :security_deposit, "Security Deposit", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :security_deposit, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :price_per_sq_ft, "Price Per Sq Ft", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :price_per_sq_ft, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :did_size, "Drive In Doors Size", class: "general-text-label" %>
<%= ff.number_field :did_size, class: "general-text-field" %>
</div>
<% end %>
更新
我更改了 ListingCommercialAttribute 模型并删除了接受嵌套属性。
我将 f.fields_for 改为单数而不是复数。
我在父级之后添加了嵌套属性(见下文)
def listing_params
params.require(:listing)
.permit(:access,
:address,
:apartment,
:cats_ok,
:cross_streets,
:dogs_ok,
:latitude,
:longitude,
:amenities,
:date_available,
:bathrooms,
:bedrooms,
:description,
:fee,
:exclusive,
:featured,
:rental,
:residential,
:landlord_contact,
:listing_agent_id,
:sales_agent_id,
:neighborhood_id,
:pets,
:photo,
:photo_tag,
:primaryphoto,
:price,
:square_feet,
:station,
:status,
:subway_line,
:term,
:title,
:utilities,
:move_in_cost,
:owner_pays,
:private,
:office_id,
:full_address,
:zip,
:convertible,
:landlord_llc,
:pinned,
:image,
listing_commercial_attribute_attributes: [
:gas_pipe_size,
:amperage,
:basement_ceiling_height,
:ceiling_height,
:door_size,
:zoning,
:previous_use,
:community_board,
:delivery_date,
:key_money,
:security_deposit,
:price_per_sq_ft,
:did_size])
end
这是我的新控制器操作:
def edit
@listing.attributes = listing_params
end
def create
@listing.attributes = listing_params
respond_to do |format|
if @listing.save
format.html { redirect_to @listing, notice: 'Listing was successfully created.' }
format.json { render json: @listing, status: :created, location: @listing }
else
format.html { render action: "new", notice: "Correct the mistakes below to create the new listing" }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
但现在我在 Listings#show 错误中收到 NoMethodError。我为商业属性创建了一个部分。既然它们在强参数中,难道不应该包括在内吗?还是我完全误解了?!
这是部分内容:
Gas Pipe Size: <%= listing_commercial_attributes.gas_pipe_size(@listing) %>
Amperage: <%= listing_commercial_attribute.amperage(@listing) %>
Basement Ceiling Height: <%= listing_commercial_attribute.basement_celing_height(@listing) %>
Ceiling Height: <%= listing_commercial_attribute.ceiling_height(@listing) %>
Door Size: <%= listing_commercial_attribute.door_size(@listing) %>
Zoning: <%= listing_commercial_attribute.zoning(@listing) %>
Build to Suit: <%= listing_commercial_attribute.build_to_suit(@listing) %>
Previous Use: <%= listing_commercial_attribute.previous_use(@listing) %>
Community Board: <%= listing_commercial_attribute.community_board(@listing) %>
Delivery Date: <%= listing_commercial_attribute.delivery_date(@listing) %>
Key Money: <%= listing_commercial_attribute.key_money(@listing) %>
更新 #2
我改成单数了
这是完整的错误。
列表中的名称错误#show
显示 /Users/Code/app/views/listings/_commercial_attributes.html.erb 第 1 行出现的位置:
#<#:0x007f86606f6a10> 的未定义局部变量或方法“listing_commercial_attribute”
你的意思? listing_collection_url
- 煤气管尺寸:<%= listing_commercial_attribute.gas_pipe_size(@listing) %>
- 电流强度:<%= listing_commercial_attribute.amperage(@listing) %>
- 地下室天花板高度:<%= listing_commercial_attribute.basement_celing_height(@listing) %>
- 天花板高度:<%= listing_commercial_attribute.ceiling_height(@listing) %>
- 门尺寸:<%= listing_commercial_attribute.door_size(@listing) %>
- 分区:<%= listing_commercial_attribute.zoning(@listing) %>
模板包含的痕迹:app/views/listings/_listing_content_area.html.erb, app/views/listings/show.html.erb
更新 #3
def show
@my_listing_collections = ListingCollection.with_agent(current_agent).order("created_at DESC")
@listing_commercial_attributes = ListingCommercialAttribute.find(params[:id])
@regions = Region.order(name: :asc)
@listing = Listing.includes(:photos, :likes, :interested_agents).find(params[:id])
if @listing.private && cannot?(:create, Listing)
redirect_to listings_path, notice: 'This listing is no longer available'
else
agent = Agent.where(id: params[:agent_id]).first
@page = Listings::ShowView.new(@listing, agent)
respond_to do |format|
format.html
end
end
end
我不断收到此错误:
ListingsController 中的 ActiveRecord::RecordNotFound#show
找不到 'id'=5755
的 ListingCommercialAttribute
它正在搜索 ID 为 5755 的商业属性,但那是列表 ID。我不确定在那里传递什么...
- 不要在两个模型上都定义
accepts_nested_attributes_for
。仅在父模型上。否则你会 运行 陷入循环依赖问题。在这种情况下,父模型看起来像是一个清单,因此从 ListingCommercialAttribute 中删除 accepts_nested_attributes_for :listing
。
f.fields_for
的第一个参数应该是协会的名称,你的有点不对。你有 has_one : listing_commerical_attribute
所以你想要 f.fields_for : listing_commerical_attribute
.
- 强参数应首先要求您的父对象,其次包括嵌套对象。此外,您必须将
_attributes
附加到嵌套属性名称的末尾。
所以,对于 3:
def listing_params
params.require(:listing)
.permit(:id,
# ...
listing_commercial_attribute_attributes: [ # Note: _attributes
:gas_pipe_size,
# ...
])
end
- 在create/edit动作中,一定要使用强参数方法设置参数:
@listing.attributes = listing_params
.
在 accepts_nested_attributes_for
and Strong Parameters 上的文档中阅读更多内容。
我正在尝试对我正在处理的项目使用 fields_for 辅助方法。原始表格可以正常工作并保存。新属性不保存,我得到一个 NoMethodError 和一个未定义的方法。我错过了什么?!
这是我的列表模型:
class Listing < ActiveRecord::Base
has_one :listing_commerical_attribute
accepts_nested_attributes_for :listing_commerical_attribute, :allow_destroy => true
这是我的 listing_commercial_attribute 模型:
class ListingCommercialAttribute < ActiveRecord::Base
belongs_to :listing
accepts_nested_attributes_for :listing
end
这是我的控制器:
def new
@listing.build_listing_commercial_attribute
respond_to do |format|
format.html # new.html.erb
format.json { render json: @listing }
end
end
private
def commercial_params
params.require(:commerical_listing_attribute)
.permit(:gas_pipe_size,
:amperage,
:basement_ceiling_height,
:ceiling_height,
:door_size,
:zoning,
:previous_use,
:community_board,
:delivery_date,
:key_money,
:security_deposit,
:price_per_sq_ft,
:did_size)
end
这是我的 _form.html.erb:
<h2 class="text-center">Commercial</h2>
<%= f.fields_for :listing_commerical_attributes do |ff| %>
<div class="field">
<%= ff.label :gas_pipe_size, "Gas Pipe Size", class: "general-text-label" %>
<%= ff.number_field :gas_pipe_size, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :amperage, "Amperage", class: "general-text-label" %>
<%= ff.number_field :amperage, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :ceiling_height, "Ceiling Height", class: "general-text-label" %>
<%= ff.number_field :ceiling_height, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :basement_ceiling_height, "Basement Ceiling Height", class: "general-text-label" %>
<%= ff.number_field :basement_ceiling_height, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :door_size, "Door Size", class: "general-text-label" %>
<%= ff.number_field :door_size, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :zoning, "Zoning", class: "general-text-label" %>
<%= ff.text_field :zoning, class: "general-text-field" %>
</div>
<div class="field">
<label for="tenant_improvements" class="general-text-label">Tenant Improvements <small>(If Applicable)</small></label>
<%= ff.text_area :tenant_improvements, :rows => "4", class: "general-text-area" %>
</div>
<div class="field">
<label for="previous_use" class="general-text-label">Previous Use <small>(If Applicable)</small></label>
<%= ff.text_area :previous_use, :rows => "4", class: "general-text-area" %>
</div>
<div class= "field">
<%= ff.label :community_board, "Community Board", class: "general-text-label" %>
<%= ff.text_field :community_board, class: "general-text-field" %>
</div>
<div class="field">
<%= ff.label :delivery_date, "Delivery Date", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-calendar"></i></span>
<%= ff.text_field :delivery_date, :class => "datepicker general-text-field" %>
</div>
<div class="field">
<%= ff.label :key_money, "Key Money", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :key_money, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :security_deposit, "Security Deposit", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :security_deposit, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :price_per_sq_ft, "Price Per Sq Ft", class: "general-text-label" %>
<div class="input-group">
<span class="input-group-addon"><i class="nklyn-icon-money-bills"></i></span>
<%= f.text_field :price_per_sq_ft, class: "general-text-field", value: number_with_precision(f.object.price, delimiter: ',', precision: 0) %>
</div>
</div>
<div class="field">
<%= ff.label :did_size, "Drive In Doors Size", class: "general-text-label" %>
<%= ff.number_field :did_size, class: "general-text-field" %>
</div>
<% end %>
更新
我更改了 ListingCommercialAttribute 模型并删除了接受嵌套属性。
我将 f.fields_for 改为单数而不是复数。
我在父级之后添加了嵌套属性(见下文)
def listing_params params.require(:listing) .permit(:access, :address, :apartment, :cats_ok, :cross_streets, :dogs_ok, :latitude, :longitude, :amenities, :date_available, :bathrooms, :bedrooms, :description, :fee, :exclusive, :featured, :rental, :residential, :landlord_contact, :listing_agent_id, :sales_agent_id, :neighborhood_id, :pets, :photo, :photo_tag, :primaryphoto, :price, :square_feet, :station, :status, :subway_line, :term, :title, :utilities, :move_in_cost, :owner_pays, :private, :office_id, :full_address, :zip, :convertible, :landlord_llc, :pinned, :image, listing_commercial_attribute_attributes: [ :gas_pipe_size, :amperage, :basement_ceiling_height, :ceiling_height, :door_size, :zoning, :previous_use, :community_board, :delivery_date, :key_money, :security_deposit, :price_per_sq_ft, :did_size]) end
这是我的新控制器操作:
def edit @listing.attributes = listing_params end def create @listing.attributes = listing_params respond_to do |format| if @listing.save format.html { redirect_to @listing, notice: 'Listing was successfully created.' } format.json { render json: @listing, status: :created, location: @listing } else format.html { render action: "new", notice: "Correct the mistakes below to create the new listing" } format.json { render json: @listing.errors, status: :unprocessable_entity } end end end
但现在我在 Listings#show 错误中收到 NoMethodError。我为商业属性创建了一个部分。既然它们在强参数中,难道不应该包括在内吗?还是我完全误解了?!
这是部分内容:
Gas Pipe Size: <%= listing_commercial_attributes.gas_pipe_size(@listing) %>
Amperage: <%= listing_commercial_attribute.amperage(@listing) %>
Basement Ceiling Height: <%= listing_commercial_attribute.basement_celing_height(@listing) %>
Ceiling Height: <%= listing_commercial_attribute.ceiling_height(@listing) %>
Door Size: <%= listing_commercial_attribute.door_size(@listing) %>
Zoning: <%= listing_commercial_attribute.zoning(@listing) %>
Build to Suit: <%= listing_commercial_attribute.build_to_suit(@listing) %>
Previous Use: <%= listing_commercial_attribute.previous_use(@listing) %>
Community Board: <%= listing_commercial_attribute.community_board(@listing) %>
Delivery Date: <%= listing_commercial_attribute.delivery_date(@listing) %>
Key Money: <%= listing_commercial_attribute.key_money(@listing) %>
更新 #2
我改成单数了
这是完整的错误。
列表中的名称错误#show
显示 /Users/Code/app/views/listings/_commercial_attributes.html.erb 第 1 行出现的位置:
#<#:0x007f86606f6a10> 的未定义局部变量或方法“listing_commercial_attribute” 你的意思? listing_collection_url
- 煤气管尺寸:<%= listing_commercial_attribute.gas_pipe_size(@listing) %>
- 电流强度:<%= listing_commercial_attribute.amperage(@listing) %>
- 地下室天花板高度:<%= listing_commercial_attribute.basement_celing_height(@listing) %>
- 天花板高度:<%= listing_commercial_attribute.ceiling_height(@listing) %>
- 门尺寸:<%= listing_commercial_attribute.door_size(@listing) %>
- 分区:<%= listing_commercial_attribute.zoning(@listing) %>
模板包含的痕迹:app/views/listings/_listing_content_area.html.erb, app/views/listings/show.html.erb
更新 #3
def show
@my_listing_collections = ListingCollection.with_agent(current_agent).order("created_at DESC")
@listing_commercial_attributes = ListingCommercialAttribute.find(params[:id])
@regions = Region.order(name: :asc)
@listing = Listing.includes(:photos, :likes, :interested_agents).find(params[:id])
if @listing.private && cannot?(:create, Listing)
redirect_to listings_path, notice: 'This listing is no longer available'
else
agent = Agent.where(id: params[:agent_id]).first
@page = Listings::ShowView.new(@listing, agent)
respond_to do |format|
format.html
end
end
end
我不断收到此错误:
ListingsController 中的 ActiveRecord::RecordNotFound#show
找不到 'id'=5755
的 ListingCommercialAttribute它正在搜索 ID 为 5755 的商业属性,但那是列表 ID。我不确定在那里传递什么...
- 不要在两个模型上都定义
accepts_nested_attributes_for
。仅在父模型上。否则你会 运行 陷入循环依赖问题。在这种情况下,父模型看起来像是一个清单,因此从 ListingCommercialAttribute 中删除accepts_nested_attributes_for :listing
。 f.fields_for
的第一个参数应该是协会的名称,你的有点不对。你有has_one : listing_commerical_attribute
所以你想要f.fields_for : listing_commerical_attribute
.- 强参数应首先要求您的父对象,其次包括嵌套对象。此外,您必须将
_attributes
附加到嵌套属性名称的末尾。
所以,对于 3:
def listing_params
params.require(:listing)
.permit(:id,
# ...
listing_commercial_attribute_attributes: [ # Note: _attributes
:gas_pipe_size,
# ...
])
end
- 在create/edit动作中,一定要使用强参数方法设置参数:
@listing.attributes = listing_params
.
在 accepts_nested_attributes_for
and Strong Parameters 上的文档中阅读更多内容。