2016-06-19 24 views
0

我想创建一个包含ActiveRecord模型Site的gem(github),该模型可以与现有Rails应用程序中的 AdminUser模型相关联。如何获得`has_many`多态关联对象的集合?

模型Site

module C80SassSeo 
    class Site < ActiveRecord::Base 
    belongs_to :owner, :polymorphic => true 
    end 
end 

模型Owner

module C80SassSeo 

    module Owner 

    extend ActiveSupport::Concern 

    # ERROR THROWN: Cannot define multiple 'included' blocks for a Concern 
    # included do 
    # 
    # end 

    def self.included(klass) 
     klass.extend ClassMethods 
     # klass.send(:include, InstanceMethods) 
    end 

    module ClassMethods 
     def act_as_owner 
     class_eval do 
      has_many :sites, :as => :owner, :class_name => 'C80SassSeo::Site' 
     end 
     end 
    end 

    end 
end 

ActiveRecord::Base.send :include, C80SassSeo::Owner 

迁移Sitec80_sass_seo_ - 表前缀):

class CreateC80SassSeoSites < ActiveRecord::Migration 
    def change 
    create_table :c80_sass_seo_sites, :options => 'COLLATE=utf8_unicode_ci' do |t| 
     t.string :url 
     t.string :owner_type # NOTE:: without this activeadmin throws an error on index Sites page 
     t.references :owner, index: true 
     t.timestamps 
    end 
    # add_foreign_key :c80_sass_seo_sites, :owners # NOTE:: migration error occurs, comment it 
    end 
end 

activeadmin为Site

ActiveAdmin.register C80SassSeo::Site, as: 'Site' do 

    scope_to :current_admin_user, association_method: :sites_list 

    menu :label => "Sites" 

    permit_params :url, :owner_id 

    config.sort_order = 'id_asc' 

    index do 
    column :url 
    actions 
    end 

    form(:html => {:multipart => true}) do |f| 

    f.inputs 'Properties' do 
     f.input :owner_id, :input_html => { :value => current_admin_user.id }, as: :hidden 
     f.input :url 
    end 

    f.actions 
    end 

end 

,但我发现一个空的收集任何时候,我尝试访问admin_user.sites的ADMINUSER例如:

=> #<ActiveRecord::Associations::CollectionProxy []> 

是获取sites_list管理员用户通过实现方法类似网站的正确方法“?

模型AdminUser(主机应用程序):

require 'c80_sass_seo/owner' 

class AdminUser < ActiveRecord::Base 
    devise :database_authenticatable, 
     :recoverable, :rememberable, :trackable, :validatable 

    act_as_owner 

    def sites_list 
    C80SassSeo::Site.where(:owner_id => self.id) 
    end 

end 

回答

0

从你的实施形式,你可能会错过另一个属性为C80SassSeo::Site纪录,这也是owner_type

两个解决方案:

  1. 添加owner_type作为隐藏输入,就像owner_id
  2. 不添加任何隐藏的输入,与admin_user.sites.create(parameters)创建网站,ActiveRecord的会照顾适当协会的你

而你提到的:

BUT I'm getting an empty collection any time I try to access admin_user.sites for a AdminUser instance: 

=> #<ActiveRecord::Associations::CollectionProxy []> 

当你看到这个,你应该仔细检查admin_user是否实际拥有任何网站?

C80SassSeo::Site.where(owner_id: admin_user.id, owner_type: 'AdminUser') 
+0

将'owner_type'添加为值为'AdminUser'的隐藏输入,然后使用此固定表单创建正确的记录来解决问题。谢谢,拉里! – c80609a

+0

不客气,很高兴提供帮助。 :) –

相关问题