rails 中的嵌套表单通过 table 多对多关系,不保存属性
Nested form in rails in many-to-many relation via through table not saving attributes
我有一个博客模型和一个标签模型,它们通过 table(模型:BlogTag)blog_tags 具有多对多关联。我在博客中实现了一个嵌套表单来为它们添加标签。
我在参数中得到 tags_attributes。但是当我保存博客对象时,它确实将标签对象保存到它,但它确实按 name = nil.
保存了它
Blog model
class Blog < ActiveRecord::Base
extend FriendlyId
friendly_id :slugurl, use: :slugged, slug_column: :slugurl
has_many :blog_tags, dependent: :destroy
has_many :tags, through: :blog_tags
accepts_nested_attributes_for :tags
def self.search(search)
words = search.to_s.downcase.strip.split.uniq
words.map! { |word| "tag ~* '\y#{word}\y'" }
psql = words.join(" OR ")
self.where(psql)
end
end
Tag model
class Tag < ActiveRecord::Base
has_many :blog_tags, dependent: :destroy
has_many :blogs, through: :blog_tags
end
BlogTag model
class BlogTag < ActiveRecord::Base
belongs_to :blog
belongs_to :tag
end
blog_controller
def new
@blog = Blog.new
@blog.tags.build
end
def create
@blog = Blog.new(blog_params)
save_tag_for
byebug
respond_to do |format|
if @blog.save
format.html { redirect_to blogs_path, notice: 'Blog was successfully created.' }
format.json { render :index, status: :created, location: @blog}
else
format.html { render :new }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
def blog_params
params.require(:blog).permit(:blog,
:title,
:slugurl,
tags_attributes: [:name]
)
end
下面可以看到,在table标签的insert命令中,name字段没有取值,因此变为nil。
Server logs
(1.2ms) BEGIN
SQL (0.9ms) INSERT INTO "blogs" ("blog", "title", "slugurl", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["blog", "<p>adsfadsfdfas</p>\r\n"], ["title", "test 11"], ["slugurl", "asdfdf"], ["created_at", "2017-07-19 08:31:32.677338"], ["updated_at", "2017-07-19 08:31:32.677338"]]
SQL (0.6ms) INSERT INTO "tags" ("created_at", "updated_at") VALUES (, ) RETURNING "id" [["created_at", "2017-07-19 08:31:32.684302"], ["updated_at", "2017-07-19 08:31:32.684302"]]
SQL (1.1ms) INSERT INTO "blog_tags" ("blog_id", "tag_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["blog_id", 20], ["tag_id", 18], ["created_at", "2017-07-19 08:31:32.706957"], ["updated_at", "2017-07-19 08:31:32.706957"]]
(8.3ms) COMMIT
Redirected to http://localhost:3000/blogs
Completed 302 Found in 33792ms (ActiveRecord: 15.8ms)
Params
{"utf8"=>"✓", "authenticity_token"=>"+1ZLYPJkQCVOkOSt6dmy9z12XgOMP+OYu0XOOzKUlv+xldd5fkB2RR/oA7qpn53YE+82FDjVeO2ylHkPIEWfVw==", "blog"=>{"title"=>"Programming Languages", "tags_attributes"=>{"0"=>{"name"=>["Python", "C#", ".NET"]}}, "slugurl"=>"pro-lang", "blog"=>"<p>asdfasdfasdf afaadf</p>\r\n"}, "commit"=>"Submit", "controller"=>"blogs", "action"=>"create"}
Form (view)
<%= form_for(@blog) do |f| %>
<% if @blog.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@blog.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% @blog.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="form-group">
<%= f.label :title ,class: 'control-label' %><br>
<%= f.text_field :title ,class: 'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class="form-group">
<%= f.fields_for :tags do |tag_builder| %>
<%= tag_builder.label :name, "Tag", class: 'control-label' %><br>
<%= tag_builder.select :name, Tag.all.pluck(:name,:name), {}, {multiple: true, class: "selectize" } %>
<%end%>
<%#= form.select :category_id, Category.all.pluck(:name,:id), {}, {multiple: true, class: "selectize"} %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class="form-group">
<%= f.label :slugurl ,class: 'control-label' %><br>
<%= f.text_field :slugurl ,class: 'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class='form-group'>
<%= f.label :blog ,class:'control-label'%><br>
<%= f.cktext_area :blog, rows: 10,class:'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="form-actions mg-t-lg">
<div class="row">
<div class="col-sm-7 col-sm-offset-5">
<div class="text-center-xs">
<input type="submit" name="commit" value="Submit" class="btn btn-contrast" />
</div>
</div>
</div>
</div>
<% end %>
I am getting tags_attributes in params. But when I save the blog
object it does save the tag object to it but it does save it by name =
nil.
根据 params
散列,您要为 name
发送多个值,因此您需要修改 blog_params
以接受 name
的多个值。
def blog_params
params.require(:blog).permit(:blog,
:title,
:slugurl,
tags_attributes: [name: []]
)
end
我有一个博客模型和一个标签模型,它们通过 table(模型:BlogTag)blog_tags 具有多对多关联。我在博客中实现了一个嵌套表单来为它们添加标签。
我在参数中得到 tags_attributes。但是当我保存博客对象时,它确实将标签对象保存到它,但它确实按 name = nil.
保存了它Blog model
class Blog < ActiveRecord::Base
extend FriendlyId
friendly_id :slugurl, use: :slugged, slug_column: :slugurl
has_many :blog_tags, dependent: :destroy
has_many :tags, through: :blog_tags
accepts_nested_attributes_for :tags
def self.search(search)
words = search.to_s.downcase.strip.split.uniq
words.map! { |word| "tag ~* '\y#{word}\y'" }
psql = words.join(" OR ")
self.where(psql)
end
end
Tag model
class Tag < ActiveRecord::Base
has_many :blog_tags, dependent: :destroy
has_many :blogs, through: :blog_tags
end
BlogTag model
class BlogTag < ActiveRecord::Base
belongs_to :blog
belongs_to :tag
end
blog_controller
def new
@blog = Blog.new
@blog.tags.build
end
def create
@blog = Blog.new(blog_params)
save_tag_for
byebug
respond_to do |format|
if @blog.save
format.html { redirect_to blogs_path, notice: 'Blog was successfully created.' }
format.json { render :index, status: :created, location: @blog}
else
format.html { render :new }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
def blog_params
params.require(:blog).permit(:blog,
:title,
:slugurl,
tags_attributes: [:name]
)
end
下面可以看到,在table标签的insert命令中,name字段没有取值,因此变为nil。
Server logs
(1.2ms) BEGIN
SQL (0.9ms) INSERT INTO "blogs" ("blog", "title", "slugurl", "created_at", "updated_at") VALUES (, , , , ) RETURNING "id" [["blog", "<p>adsfadsfdfas</p>\r\n"], ["title", "test 11"], ["slugurl", "asdfdf"], ["created_at", "2017-07-19 08:31:32.677338"], ["updated_at", "2017-07-19 08:31:32.677338"]]
SQL (0.6ms) INSERT INTO "tags" ("created_at", "updated_at") VALUES (, ) RETURNING "id" [["created_at", "2017-07-19 08:31:32.684302"], ["updated_at", "2017-07-19 08:31:32.684302"]]
SQL (1.1ms) INSERT INTO "blog_tags" ("blog_id", "tag_id", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["blog_id", 20], ["tag_id", 18], ["created_at", "2017-07-19 08:31:32.706957"], ["updated_at", "2017-07-19 08:31:32.706957"]]
(8.3ms) COMMIT
Redirected to http://localhost:3000/blogs
Completed 302 Found in 33792ms (ActiveRecord: 15.8ms)
Params
{"utf8"=>"✓", "authenticity_token"=>"+1ZLYPJkQCVOkOSt6dmy9z12XgOMP+OYu0XOOzKUlv+xldd5fkB2RR/oA7qpn53YE+82FDjVeO2ylHkPIEWfVw==", "blog"=>{"title"=>"Programming Languages", "tags_attributes"=>{"0"=>{"name"=>["Python", "C#", ".NET"]}}, "slugurl"=>"pro-lang", "blog"=>"<p>asdfasdfasdf afaadf</p>\r\n"}, "commit"=>"Submit", "controller"=>"blogs", "action"=>"create"}
Form (view)
<%= form_for(@blog) do |f| %>
<% if @blog.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@blog.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% @blog.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="form-group">
<%= f.label :title ,class: 'control-label' %><br>
<%= f.text_field :title ,class: 'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class="form-group">
<%= f.fields_for :tags do |tag_builder| %>
<%= tag_builder.label :name, "Tag", class: 'control-label' %><br>
<%= tag_builder.select :name, Tag.all.pluck(:name,:name), {}, {multiple: true, class: "selectize" } %>
<%end%>
<%#= form.select :category_id, Category.all.pluck(:name,:id), {}, {multiple: true, class: "selectize"} %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class="form-group">
<%= f.label :slugurl ,class: 'control-label' %><br>
<%= f.text_field :slugurl ,class: 'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class='form-group'>
<%= f.label :blog ,class:'control-label'%><br>
<%= f.cktext_area :blog, rows: 10,class:'form-control' %>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="form-actions mg-t-lg">
<div class="row">
<div class="col-sm-7 col-sm-offset-5">
<div class="text-center-xs">
<input type="submit" name="commit" value="Submit" class="btn btn-contrast" />
</div>
</div>
</div>
</div>
<% end %>
I am getting tags_attributes in params. But when I save the blog object it does save the tag object to it but it does save it by name = nil.
根据 params
散列,您要为 name
发送多个值,因此您需要修改 blog_params
以接受 name
的多个值。
def blog_params
params.require(:blog).permit(:blog,
:title,
:slugurl,
tags_attributes: [name: []]
)
end