Rails 多对多:通过关联
Rails Many-to-many :through association
我是 Rails 的新手,并且已经为此工作了 3-4 天。我已经创建了一个多对多 :through 关联,但是当我提交一个新对象时,我得到这个错误:
#<ActiveModel::Errors:0x007fbced7cda88 @base=#<BlogPost id: nil, created_at: nil, updated_at: nil, title: "title 13", content: "pajfposjpfej 13", posted_by: "poster 13", comments: nil, blog_pic: nil>, @messages={:"categorizations.blog_post"=>["must exist"], :title=>[], :posted_by=>[], :content=>[], :blog_pic=>[]}, @details={"categorizations.blog_post"=>[{:error=>:blank}]}>
我正在提交的表单提交我正在选择一个类别,因此它不应像错误指示的那样为空。非常感谢对此的任何帮助。这几天心灰意冷。
型号:
class BlogPost < ApplicationRecord
has_many :categorizations
has_many :categories, :through => :categorizations
accepts_nested_attributes_for :categorizations
has_many :comments
mount_uploader :blog_pic, BlogPicUploader
end
class Categorization < ApplicationRecord
belongs_to :blog_post
belongs_to :category
end
class Category < ApplicationRecord
has_many :categorizations
has_many :blog_posts, :through => :categorizations
end
views/blog_posts/new.html.erb
<%= form_for @blog_post do |b| %>
<%= b.label :title %>
<%= b.text_field :title %><br>
<%= b.fields_for :categorizations do |cat| %>
<%= cat.label :category_name, "Category 1" %>
<%= cat.collection_select(:category_id, Category.all, :id, :category_name, include_blank: "Select Category") %><br>
<% end %>
<%= b.submit "Submit", class: "btn btn-primary" %>
<% end %>
控制器:
class BlogPostsController < ApplicationController
def index
@blog_posts = BlogPost.order(id: :desc)
end
def new
@blog_post = BlogPost.new
@categorizations = @blog_post.categorizations.build
@categories = @blog_post.categories.build
end
...
def create
@blog_post = BlogPost.new(blog_post_params)
respond_to do |format|
if @blog_post.save
format.html { redirect_to @blog_post, notice: 'Your blog was submitted successfully' }
format.json { render :show, status: :created, location: @blog_post }
else
format.html { render :new }
format.json { render json: @blog_post.errors, status: :unprocessable_entity }
end
end
puts @blog_post.errors.inspect
end
private
def blog_post_params
params.require(:blog_post).permit(:title, :content, :posted_by, :comments, :blog_pic, {categorizations_attributes: [:category_id, :category_name]})
end
end
您还需要为 categories
声明嵌套属性。
喜欢:
class BlogPost < ApplicationRecord
has_many :categorizations
has_many :categories, :through => :categorizations
accepts_nested_attributes_for :categorizations
accepts_nested_attributes_for :categories
has_many :comments
mount_uploader :blog_pic, BlogPicUploader
end
您可以参考下面link的描述
https://hackhands.com/building-has_many-model-relationship-form-cocoon/
这里的答案与代码无关 - 简单地说 - 在 Rails 5 中,他们进行了更改,现在默认需要 belongs_to 关联,而 Rails 4,这是可选的。请参阅下面的 link 解释:
http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html
您必须将 config/initializers/new_framework_defaults 中的这一行从 true
更改为 false
:
Rails.application.config.active_record.belongs_to_required_by_default = false
我是 Rails 的新手,并且已经为此工作了 3-4 天。我已经创建了一个多对多 :through 关联,但是当我提交一个新对象时,我得到这个错误:
#<ActiveModel::Errors:0x007fbced7cda88 @base=#<BlogPost id: nil, created_at: nil, updated_at: nil, title: "title 13", content: "pajfposjpfej 13", posted_by: "poster 13", comments: nil, blog_pic: nil>, @messages={:"categorizations.blog_post"=>["must exist"], :title=>[], :posted_by=>[], :content=>[], :blog_pic=>[]}, @details={"categorizations.blog_post"=>[{:error=>:blank}]}>
我正在提交的表单提交我正在选择一个类别,因此它不应像错误指示的那样为空。非常感谢对此的任何帮助。这几天心灰意冷。
型号:
class BlogPost < ApplicationRecord
has_many :categorizations
has_many :categories, :through => :categorizations
accepts_nested_attributes_for :categorizations
has_many :comments
mount_uploader :blog_pic, BlogPicUploader
end
class Categorization < ApplicationRecord
belongs_to :blog_post
belongs_to :category
end
class Category < ApplicationRecord
has_many :categorizations
has_many :blog_posts, :through => :categorizations
end
views/blog_posts/new.html.erb
<%= form_for @blog_post do |b| %>
<%= b.label :title %>
<%= b.text_field :title %><br>
<%= b.fields_for :categorizations do |cat| %>
<%= cat.label :category_name, "Category 1" %>
<%= cat.collection_select(:category_id, Category.all, :id, :category_name, include_blank: "Select Category") %><br>
<% end %>
<%= b.submit "Submit", class: "btn btn-primary" %>
<% end %>
控制器:
class BlogPostsController < ApplicationController
def index
@blog_posts = BlogPost.order(id: :desc)
end
def new
@blog_post = BlogPost.new
@categorizations = @blog_post.categorizations.build
@categories = @blog_post.categories.build
end
...
def create
@blog_post = BlogPost.new(blog_post_params)
respond_to do |format|
if @blog_post.save
format.html { redirect_to @blog_post, notice: 'Your blog was submitted successfully' }
format.json { render :show, status: :created, location: @blog_post }
else
format.html { render :new }
format.json { render json: @blog_post.errors, status: :unprocessable_entity }
end
end
puts @blog_post.errors.inspect
end
private
def blog_post_params
params.require(:blog_post).permit(:title, :content, :posted_by, :comments, :blog_pic, {categorizations_attributes: [:category_id, :category_name]})
end
end
您还需要为 categories
声明嵌套属性。
喜欢:
class BlogPost < ApplicationRecord
has_many :categorizations
has_many :categories, :through => :categorizations
accepts_nested_attributes_for :categorizations
accepts_nested_attributes_for :categories
has_many :comments
mount_uploader :blog_pic, BlogPicUploader
end
您可以参考下面link的描述
https://hackhands.com/building-has_many-model-relationship-form-cocoon/
这里的答案与代码无关 - 简单地说 - 在 Rails 5 中,他们进行了更改,现在默认需要 belongs_to 关联,而 Rails 4,这是可选的。请参阅下面的 link 解释:
http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html
您必须将 config/initializers/new_framework_defaults 中的这一行从 true
更改为 false
:
Rails.application.config.active_record.belongs_to_required_by_default = false