2013-05-14 79 views
2

我们在rails/activerecord中存在多态关系的问题。 正如其他question中所述。 我们需要这种带整数foreign_type列的多态关系的原因是表中的记录数,我们在该表中有大约4000万条记录正在提高。我们试图在数据库服务器上保存与存储索引处理相关的内存消耗。Rails 3与foreign_type列的多态关联作为整数

前面提到的问题与Rails 2有关,如果已经试图在Rails 3中使用它,但它不起作用。该模块的方法从来没有被调用,我不明白为什么。

我想有一个这样的映射与列类型看到在迁移类

class Notification < ActiveRecord::Base 
    belongs_to :notifiable, :polymorphic => true 
end 
class User < ActiveRecord::Base 
    attr_accessible :name 
    has_many :notifications, :as => :notifiable 
end 
class Comment < ActiveRecord::Base 
    attr_accessible :text 
    has_many :notifications, :as => :notifiable 
end 
class Message < ActiveRecord::Base 
    attr_accessible :title, :text 
    has_many :notifications, :as => :notifiable 
end 
class Activity < ActiveRecord::Base 
    attr_accessible :title, :description 
    has_many :notifications, :as => :notifiable 
end 
class CreateNotification < ActiveRecord::Migration 
    def change 
    create_table :notifications do |t| 
     t.integer :notifiable_id 
     t.integer :notifiable_type # should be a tinyint at the database 
     t.timestamps 
    end 
    end 
end 

我想映射注释和用户使用数字值并保存数值而不是类n作为类型信息。

+0

真的吗?将字符串中的“类型”列更改为整数是成功还是失败?你有没有分析过这个? – messick 2013-05-14 06:26:18

+0

最大的问题是*为什么*你想这样做?类型列是一个字符串的原因。你为什么要它返回一个整数?为什么只是客人? – 2013-05-14 06:32:03

+0

@TarynEast这只是一个例子。我们已经建立了一个社交社区,并将任何触发器与通知表关联起来,这些通知表可能是用户,活动,评论,参与,观察,私人消息等等。目前,通知或新闻的数量约为4千万。 – motionless 2013-05-14 08:24:43

回答

0

你试过:

class CreateNotification < ActiveRecord::Migration 
    def change 
    create_table :notifications do |t| 
     t.integer :notifiable_id 
     t.integer :notifiable_type_id # should be a tinyint at the database 
     t.timestamps 
    end 
    end 
end 

Rails会假设,如果你把它; “notifiable_type”然后它是IS一种类型。

但是,如果您将其称为notifiable_type_id,那么rails会认为它是属于名为notifiable_type的模型的整数id。

您可能还需要添加一个notifiable_type模型,并为每个您所拥有的类添加ID或者它可能只是正常工作......但这绝对是我要开始的地方。

+0

感谢您的答案,但是将“notifiable_type_id”添加到数据库的不同类的值?如果已经测试了您的建议,但数据库列为空。 – motionless 2013-05-15 09:30:15

+0

正如我所说 - 这是一个开始的地方,而不是一个完整的解决方案...称之为读者的练习;) – 2013-05-16 07:02:04

+0

感谢您的初始位置开始,但我没有能够比你的建议更进一步。我已经用调试和覆盖的方法尝试过了,但是我不能改变持久层的行为,它总是忽略这个值。也许它迟到了,但我看不出问题所在。 – motionless 2013-06-04 18:46:04

2

为了使多态性belongs_to的工作,你可以这样做:

config/initializers目录下创建一个文件,并把论文线:

module ActiveRecord 
    # = Active Record Belongs To Polymorphic Association 
    module Associations 
    class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc: 
     def klass 
     type = owner.send(reflection.foreign_type) 
     type.presence && type.constantize 
     end 
    end 
    end 
end 

然后在每个模型,覆盖notifiable_type(定义哈希作为一个常数,把它放在任何你喜欢):

def notifiable_type 
    { 0: 'User', 1: 'Comment', 3: 'Message' }[read_attribute(:notifiable_type)] 
end 

has_many,试试这个(套INT_CLASS_TYPE˚F或每个型号):

has_many :notifications, :conditions => ["`notifiable_type` = ?", INT_CLASS_TYPE], :foreign_key => 'notifiable_id'