我无法获得has_many:通过协会工作。我是否需要在post_controller的create方法中设置额外的东西,以保存post_category? (代码下方,错误和我的尝试)
我有一个has_many:通过关联post,post_category和连接表分类如下:
邮政模型:
class Post < ApplicationRecord
has_many :categorizations
has_many :post_categories, :through => :categorizations
end
Post :: Category Model(使用命名空间以获得更好的项目结构):
class Post::Category < ApplicationRecord
has_many :categorizations
has_many :posts, :through => :categorizations
end
分类模型(使用class_name,Post :: Category命名空间的原因):
class Categorization < ApplicationRecord
belongs_to :post
belongs_to :post_category, :class_name => 'Post::Category'
end
然后我在视图中选择了我用post_category创建帖子的地方:
<div class="form-group">
<%= f.label :post_categories, :class => 'control-label', :value => 'Category: ' %>
<%= f.select :post_categories, options_from_collection_for_select(all_post_categories, :id, :name), {}, {class: 'selectpicker', :'data-live-search' => 'true', required: 'false' } %>
</div>
在posts_controller中,我允许使用:post_categories
符号:
def post_params
params.require(:post).permit(:post_categories)
end
以下是我的协会迁移文件:
class CreateCategorizations < ActiveRecord::Migration[5.0]
def change
create_table :categorizations do |t|
t.integer :post_id
t.integer :post_category_id
t.timestamps
end
add_index :categorizations, :post_id
add_index :categorizations, :post_category_id
# multiple-key index enforces uniqueness on (post_id, post_category_id)
# pairs, so that a category can't have the same post twice
add_index :categorizations, [:post_id, :post_category_id], unique: true
end
end
当我尝试提交表单时,我在日志中收到以下错误:
NoMethodError (undefined method `each' for "3":String):
app/controllers/posts_controller.rb:32:in `create'
所以我搜索了一些好的答案 - &gt; You can't assign string to association
我尝试了另一种方法让这种关联发挥作用。
所以我尝试使用post_category_id,就像推荐的here
一样我在视图的选择中设置了
<%= f.select :post_category_id, options_from_collection_for_select(all_post_categories, :id, :name), {}, {class: 'selectpicker', :'data-live-search' => 'true', required: 'false' } %>
然后在posts_controller中允许category_id:
def post_params
params.require(:post).permit(:post_category_id)
end
并在Post模型中:
class Post < ApplicationRecord
has_many :categorizations
has_many :post_category_id, :through => :categorizations
end
这是新错误:
Could not find the source association(s) "post_category_id" or :post_category_id in model Categorization. Try 'has_many :post_category_id, :through => :categorizations, :source => <name>'. Is it one of post or post_category?
好的,因为没有post_category_id
关联。
更新
post_params:
<ActionController::Parameters {"content"=>"content", "post_categories"=>"2"} permitted: true>
答案 0 :(得分:1)
我通过此answer和此question为我找到了正确的解决方案。
第一个解决方案只保存一个Post :: Category with Post
关于这个answer,我不得不将posts_controller中的permit参数更改为:
def post_params
params.require(:post).permit(:post_category_ids)
end
然后我还需要更改视图中的选择,我在其中创建一个带有post_category的帖子:
<div class="form-group">
<%= f.label :post_category_ids, :class => 'control-label', :value => 'Category: ' %>
<%= f.select :post_category_ids, options_from_collection_for_select(all_post_categories, :id, :name), {}, {class: 'selectpicker', :'data-live-search' => 'true', required: 'false' } %>
</div>
那就是它。其余的代码仍然与我在第二次尝试之前展示的相同。
使用帖子保存多个Post :: Category的第二个解决方案
关于这个question,我需要将posts_controller中的permit参数更改为:
def post_params
params.require(:post).permit(:post_category_ids => [])
end
要同时选择多个Post :: Category,我需要在视图中的select中添加multiple: 'true'
:
<div class="form-group">
<%= f.label :post_category_ids, :class => 'control-label', :value => 'Category: ' %>
<%= f.select :post_category_ids, options_from_collection_for_select(all_post_categories, :id, :name), {}, {class: 'selectpicker', :'data-live-search' => 'true', required: 'false', multiple: 'true' } %>
</div>
答案 1 :(得分:0)
我认为你需要改变这个:
<%= f.select :post_categories, options_from_collection_for_select(all_post_categories, :id, :name), {}, {class: 'selectpicker', :'data-live-search' => 'true', required: 'false' } %>
到此:
<%= f.select :post_categories[:id],
options_from_collection_for_select(all_post_categories, :id, :name),
class: 'selectpicker', :'data-live-search' => 'true', required: 'false' , include_hidden: false} %>
如果我错了,请拍我。
编辑:包含hidden:false for rails 4.2+