Rails 4.2 嵌套表单--SQL 加载'Edit' 页面时自动删除嵌套表单内容
Rails 4.2 Nested Forms--SQL Automatically Deleted Nested Forms Content When Loading 'Edit' Page
我使用这个 Blog 作为在 Ruby on Rails 4.2
上学习 nested form
的指南。我尝试使用此指令中的相同步骤在 Post
模型中创建位置嵌套表单。
使用嵌套位置表单创建新的 post
后,位置内容在 post's
显示页面上正确显示。但是,当我打开 edit
页面时,位置内容全部消失了。仔细查看日志,发现如下信息:
Started GET "/categories/category#name/posts/323/edit"...
Location Load (0.1ms) SELECT "locations".* FROM "locations" WHERE "locations"."post_id" = ? LIMIT 1 [["post_id", 323]]
(0.1ms) begin transaction
SQL (0.4ms) DELETE FROM "locations" WHERE "locations"."id" = ? [["id", 27]]
似乎嵌套形式创建的内容在加载编辑页面时被SQL自动删除了。
这是我的代码:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_one :location, dependent: :destroy
accepts_nested_attributes_for :location, reject_if: lambda { |a| a['street'].blank? },
allow_destroy: true
def to_s
title
end
end
位置模型:
class Location < ActiveRecord::Base
belongs_to :post
has_one :user, through: :post
validates :city, presence: true
validates :zipcode, presence: true,
format: { with: /\A\d{5}\z/i }
end
帖子控制器:
class Categories::PostsController < ApplicationController
...
def new
@category = Category.friendly.find(params[:category_id])
@post = Post.new
@post.build_location
end
def create
@category = Category.friendly.find(params[:category_id])
@post = current_user.posts.build(post_params)
@post.category = @category
if @post.save
flash[:success] = "You have succesfully created a new post."
redirect_to [@category, @post]
else
flash[:error] = "Error occured. Please try again."
render :new
end
end
def edit
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
@post.build_location
end
def update
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
if @post.update_attributes(post_params)
flash[:success] = "Post was upated."
redirect_to [@category, @post]
else
flash[:error] = "There was an error saving a post, please try again."
render :new
end
end
...
private
def post_params
params.require(:post).permit(:title, :body, location_attributes: [:id, :street, :city, :zipcode, :_destroy])
end
app/views/posts/_form.html.erb
<%= form_for [@category, @post] do |f| %>
...
<strong>Location:</strong>
<div class="well">
<%= f.fields_for :location do |location| %>
<%= location.label :street %>
<%= location.text_field :street, placeholder: "If you don't want to provide your address, just put 'NA' in this field" %>
<%= location.label :city %>
<%= location.text_field :city %>
<%= location.label :zipcode%>
<%= location.text_field :zipcode %>
<%= location.check_box :_destroy %>
<%= location.label :_destroy, 'remove' %>
<% end %>
</div>
虽然按照我遵循的说明一切正常,但当我在服务器上测试我的应用程序时,我的应用程序不断出现 "silent" 错误。如何使嵌套表单中的现有数据出现在编辑页面上?
欢迎任何见解,并提前致谢!
@post.build_location
在内存中创建一个新的位置对象,因此它被传递给 update
并因此删除与 post 关联的位置。它不获取当前位置。
@post.create_location
还创建了一个新的位置对象,但将其与数据库相同。这不是你想要的。
我将从编辑操作中删除 @post.build_location
。该视图应该工作,因为它已经在寻找 post
的 location
,这与 @post.location
相同
编辑
您可能想要如下行为:
- 如果 Post 有位置,在 Post
的编辑中显示当前位置
- 如果 Post 没有位置,在 Post
的编辑中显示空白字段
为此,只有当 Post 没有 Location 时,您才需要在编辑操作中构建 Location 对象。
def edit
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
@post.build_location if @post.location.nil?
end
这是您在编辑操作中需要的
当您调用 @post.build_location
时,它会从数据库中清除您的旧位置。
在 "When are objects saved?"
上查看 Rails 指南
例如:
a = Whole.new
a.save
a
=> #<Whole id: 2, name: "foo", created_at: "2015-09-02 05:15:15", updated_at: "2015-09-02 05:15:15">
a.part
=> nil
b = a.build_part
b.save
a.part
=> #<Part id: 1, name: nil, created_at: "2015-09-02 05:16:37", updated_at: "2015-09-02 05:16:37", whole_id: 2>
c = a.build_part
=> #<Part id: nil, name: nil, created_at: nil, updated_at: nil, whole_id: 2>
Part.find_by(whole_id: 2)
=> nil
如果还没有,您也可以只建立一个新位置:
@post.build_location unless @post.location
更新控制器中的编辑方法。仅在 post 没有关联位置时构建实例。
@post.build_location if @post.location.blank?
我使用这个 Blog 作为在 Ruby on Rails 4.2
上学习 nested form
的指南。我尝试使用此指令中的相同步骤在 Post
模型中创建位置嵌套表单。
使用嵌套位置表单创建新的 post
后,位置内容在 post's
显示页面上正确显示。但是,当我打开 edit
页面时,位置内容全部消失了。仔细查看日志,发现如下信息:
Started GET "/categories/category#name/posts/323/edit"...
Location Load (0.1ms) SELECT "locations".* FROM "locations" WHERE "locations"."post_id" = ? LIMIT 1 [["post_id", 323]]
(0.1ms) begin transaction
SQL (0.4ms) DELETE FROM "locations" WHERE "locations"."id" = ? [["id", 27]]
似乎嵌套形式创建的内容在加载编辑页面时被SQL自动删除了。
这是我的代码:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_one :location, dependent: :destroy
accepts_nested_attributes_for :location, reject_if: lambda { |a| a['street'].blank? },
allow_destroy: true
def to_s
title
end
end
位置模型:
class Location < ActiveRecord::Base
belongs_to :post
has_one :user, through: :post
validates :city, presence: true
validates :zipcode, presence: true,
format: { with: /\A\d{5}\z/i }
end
帖子控制器:
class Categories::PostsController < ApplicationController
...
def new
@category = Category.friendly.find(params[:category_id])
@post = Post.new
@post.build_location
end
def create
@category = Category.friendly.find(params[:category_id])
@post = current_user.posts.build(post_params)
@post.category = @category
if @post.save
flash[:success] = "You have succesfully created a new post."
redirect_to [@category, @post]
else
flash[:error] = "Error occured. Please try again."
render :new
end
end
def edit
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
@post.build_location
end
def update
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
if @post.update_attributes(post_params)
flash[:success] = "Post was upated."
redirect_to [@category, @post]
else
flash[:error] = "There was an error saving a post, please try again."
render :new
end
end
...
private
def post_params
params.require(:post).permit(:title, :body, location_attributes: [:id, :street, :city, :zipcode, :_destroy])
end
app/views/posts/_form.html.erb
<%= form_for [@category, @post] do |f| %>
...
<strong>Location:</strong>
<div class="well">
<%= f.fields_for :location do |location| %>
<%= location.label :street %>
<%= location.text_field :street, placeholder: "If you don't want to provide your address, just put 'NA' in this field" %>
<%= location.label :city %>
<%= location.text_field :city %>
<%= location.label :zipcode%>
<%= location.text_field :zipcode %>
<%= location.check_box :_destroy %>
<%= location.label :_destroy, 'remove' %>
<% end %>
</div>
虽然按照我遵循的说明一切正常,但当我在服务器上测试我的应用程序时,我的应用程序不断出现 "silent" 错误。如何使嵌套表单中的现有数据出现在编辑页面上?
欢迎任何见解,并提前致谢!
@post.build_location
在内存中创建一个新的位置对象,因此它被传递给 update
并因此删除与 post 关联的位置。它不获取当前位置。
@post.create_location
还创建了一个新的位置对象,但将其与数据库相同。这不是你想要的。
我将从编辑操作中删除 @post.build_location
。该视图应该工作,因为它已经在寻找 post
的 location
,这与 @post.location
编辑 您可能想要如下行为:
- 如果 Post 有位置,在 Post 的编辑中显示当前位置
- 如果 Post 没有位置,在 Post 的编辑中显示空白字段
为此,只有当 Post 没有 Location 时,您才需要在编辑操作中构建 Location 对象。
def edit
@category = Category.friendly.find(params[:category_id])
@post = Post.find(params[:id])
@post.build_location if @post.location.nil?
end
这是您在编辑操作中需要的
当您调用 @post.build_location
时,它会从数据库中清除您的旧位置。
在 "When are objects saved?"
上查看 Rails 指南例如:
a = Whole.new
a.save
a
=> #<Whole id: 2, name: "foo", created_at: "2015-09-02 05:15:15", updated_at: "2015-09-02 05:15:15">
a.part
=> nil
b = a.build_part
b.save
a.part
=> #<Part id: 1, name: nil, created_at: "2015-09-02 05:16:37", updated_at: "2015-09-02 05:16:37", whole_id: 2>
c = a.build_part
=> #<Part id: nil, name: nil, created_at: nil, updated_at: nil, whole_id: 2>
Part.find_by(whole_id: 2)
=> nil
如果还没有,您也可以只建立一个新位置:
@post.build_location unless @post.location
更新控制器中的编辑方法。仅在 post 没有关联位置时构建实例。
@post.build_location if @post.location.blank?