我实际上在我的应用程序中创建了一个分类系统。这是我的表架构:
分类
class CreateTaxonomies < ActiveRecord::Migration
def change
create_table :taxonomies do |t|
t.references :taxonomable, polymorphic: true
t.integer :term_id
end
end
end
条款
class CreateTerms < ActiveRecord::Migration
def change
create_table :terms do |t|
t.string :name
t.string :type
t.integer :parent_id, default: 0
end
end
end
以下是我的协会:
class Taxonomy < ActiveRecord::Base
belongs_to :taxonomable, polymorphic: true
end
class Term < ActiveRecord::Base
self.inheritance_column = :_type_disabled // because I use type as table field
has_many :taxonomies, as: :taxonomable
end
为了使它更通用,我创造了一个问题:
module Taxonomable
extend ActiveSupport::Concern
included do
has_many :taxonomies, as: :taxonomable
end
def get_associate_terms
terms = self.taxonomies.map { |t| t.term_id }
taxonomies = Term.find terms
end
end
我将它包含在我的模型中:
class Post < ActiveRecord::Base
include Taxonomable
end
它工作正常,我可以使用get_associate_terms
检索相关数据。我的问题出在我的控制器和表格中。我实际上是这样保存的:
# posts/_form.html.haml
= f.select :taxonomy_ids, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
# PostsController
def create
@post = current_user.posts.new( post_params )
if @post.save
@post.taxonomies.create( term_id: params[:post][:taxonomy_ids] )
redirect_to posts_path
else
render :new
end
end
此create方法正确保存数据但是如果你看一下params属性,你会发现对象taxonomies
正在等待term_id
,但我只能使用{{1在我的形式。感觉有点脏,我想要你的观点,以避免这样的黑客攻击。
另外,我认为这个问题与上面的问题有关,在编辑我的项目时,选中框不会检查与当前帖子关联的实际匹配类别。
欢迎任何想法。
非常感谢
编辑:
这是我的表格
taxonomy_ids
编辑2:
我将= form_for @post, url: posts_path, html: { multipart: true } do |f|
= f.select :taxonomy_ids, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
添加到我的关注中:
accepts_nested_attributes_for
然后在我的表单中使用module Taxonomable
include do
has_many :taxonomies, as: :taxonomable, dependent: :destroy
accepts_nested_attributes_for :taxonomies
end
end
:
fields_for
提交表单时,我会收到:
= f.fields_for :taxonomies_attributes do |taxo|
= taxo.label :term_id, 'Categories'
= taxo.select :term_id, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
但是,当帖子成功保存后,关联不会。任何想法???
编辑3:
在我的控制器中,我添加了这个:
"post"=>{"type"=>"blog", "taxonomies_attributes"=>{"term_id"=>"2"}, "reference"=>"TGKHLKJ-567TYGJGK", "name"=>"My super post"
提交表单时,我收到以下错误:
def post_params
params.require(:post).permit(
taxonomies_attributes: [:term_id]
)
end
根据该帖Rails 4 nested form - no implicit conversion of Symbol into Integer,因为我在no implicit conversion of Symbol into Integer
中使用taxonomies_attributes
作为:
fields_for
但是,如果我将其删除为:
= f.fields_for :taxonomies_attributes do |taxo|
该块除了包裹div之外什么也没有显示:
= f.fields_for :taxonomies do |taxo|
编辑4:
最后让它有效。选择框未显示的事实来自于创建新资源时,我的<div class="form-group">
<!-- Should be display here but nothing -->
</div>
没有分类法。执行以下操作修复:
@post
感谢所有人
答案 0 :(得分:2)
我不确定我是否完全理解你的问题,但我注意到的一件事是你真的不需要分两步保存。
只需将以下行添加到Taxonomable
模块(Rails 3)
attr_accessible :taxonomies_attributes
accepts_nested_attributes_for :taxonomies
如果您使用的是Rails 4,只需将accepts_nested_attributes_for
添加到Taxonomable
模块和每个控制器,请确保允许分类法属性。例如,在PostsController
中,将以下内容添加到
def post_params
params.require(:post).permit(:name, taxonomies_attributes: [:name])
end
您的创建将更改为:
def create
@post = current_user.posts.new( post_params )
if @post.save
redirect_to posts_path
else
render :new
end
end
这假设您的表单通过fields_for
使用了正确的嵌套 - 我不确定,因为您没有发布表单代码。