Rails最佳实践,使用多态关联

纸箱

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

分类法

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正在等待a,term_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_attributesfields_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

谢谢大家

拉杰什·科拉帕卡姆(Rajesh Kolappakam)

我不确定我是否完全理解您的问题,但是我注意到的一件事是,您实际上不需要分两步进行保存。

只需将以下行添加到您的Taxonomable模块中(Rails 3)

attr_accessible :taxonomies_attributes
accepts_nested_attributes_for :taxonomies

如果您使用的是Rails 4,则仅将,添加accepts_nested_attributes_forTaxonomable模块以及每个Controller中,请确保允许使用分类法属性。例如,在中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-我不确定,因为您没有发布表单代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章