1

我实际上是在我的应用程序中创建一个分类系统。这是我的表架构:

分类法

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

此创建方法正确保存数据,但如果您查看 params 属性,您会看到该对象taxonomies正在等待 aterm_id但我只能taxonomy_ids在我的表单中使用。感觉有点脏,我想听听你的观点,以避免那样乱搞。

另外,我认为这个问题与上面的问题有关,在编辑我的项目时,选择框没有选中与当前帖子关联的实际匹配类别。

欢迎任何想法。

非常感谢

编辑:
这是我的表格

= 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'

编辑2:
我添加了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'

提交表单时,我收到它:

"post"=>{"type"=>"blog", "taxonomies_attributes"=>{"term_id"=>"2"}, "reference"=>"TGKHLKJ-567TYGJGK", "name"=>"My super post"

但是,当帖子已成功保存时,关联不会。有任何想法吗???

编辑 3:
在我的控制器中,我添加了这个:

def post_params
  params.require(:post).permit(
    taxonomies_attributes: [:term_id]
  )
end

提交表单时,出现以下错误:

no implicit conversion of Symbol into Integer

根据该帖子Rails 4 嵌套形式 - 没有将 Symbol 隐式转换为 Integer,这是因为我taxonomies_attributes在我的fields_foras 中使用:

= f.fields_for :taxonomies_attributes do |taxo|

但是,如果我将其删除为:

= f.fields_for :taxonomies do |taxo|

除了包装它的 div 之外,该块不显示任何内容:

<div class="form-group">
  <!-- Should be display here but nothing -->
</div>

编辑 4:
最后让它工作。选择框未显示的事实来自于在创建新资源时,我@post没有分类法。执行以下修复:

def new
  @product    = current_user.products.new
  category    = @product.taxonomies.build
end

谢谢大家

4

1 回答 1

3

我不确定我是否完全理解你的问题,但我注意到的一件事是你真的不需要分两步保存。

只需将以下行添加到您的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- 我不确定,因为您没有发布表单代码。

于 2013-09-27T06:01:36.367 回答