3

我们在 rails/activerecord 中的多态关系存在一定的问题。如另一个问题所述。我们需要这种具有整数 foreign_type 列的多态关系的原因是表中的记录数,我们在该表中有大约 4000 万条记录,而且这个数字还在增加。我们尝试在数据库服务器上节省存储空间,以节省与数据库中的索引处理有关的内存消耗。

前面提到的问题与 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

I would like to map Comment and User with a numeric value and save the numeric value instead of the class name as type information.

4

2 回答 2

3

To make the polymorphic belongs_to working, you can do that:

In config/initializers directory, create a file and put theses lines:

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

then in each model, override notifiable_type (define the hash as a constant and put it anywhere you like):

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

and for has_many, try this (set INT_CLASS_TYPE for each model):

has_many :notifications, :conditions => ["`notifiable_type` = ?", INT_CLASS_TYPE], :foreign_key => 'notifiable_id'
于 2013-07-05T09:37:52.233 回答
0

Have you tried:

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 will assume that if you call it; "notifiable_type" then it IS a type.

but if you call it notifiable_type_id then rails will assume it is an integer id belonging to a model called notifiable_type.

You may need to add a notifiable_type model too and include ids for each of the classes you have... or it might Just Work... but that's definitely where I'd start.

于 2013-05-15T04:25:02.617 回答