开发者

modeling global indentification for different objects in Rails 3.1

I have a system where I want 开发者_如何学Ca global identifier for objects in rails. The global identification is a number (or alpha-numeric) that is shared across a bunch of objects. When you save an object you will insert a global identificaiton value that is based upon an object and an object_id.

So for example:

location id=3

id=15
arc_type='location'
arc_id=3
arc_value=loc-3

So the question is can I do a has_one using a composite foreign key of object_type and object_id. Or would I need to a foreign key like the object value, a shortened name and the id of the original object.

Or perhaps use a different scenario such as an md5 hash as foreign key.

Would this be a candidate for doing a polymorphic association? It seems like that would be more appropriate for the has_many rather than has_one (such as pictuers or comments). Has anyone ever done a has_one with a polymorphic assoication?

thx

edit - looks like the object_id name is a bad idea so i've substituted arc_ which is initials of project


I'm not sure about the composite foreign key in Rails since the has_one association only seems to have :primary_key and :foreign_key options. See more here.

I have accomplished something very similar to this recently though. At a high level, I added a uuid field to all the models that I want to uniquely identify along with a shared bit of code that generates the UUID on save. Now that each object has a unique identifier, I can use Rail's :primary_key and :foreign_key to build associations as I please. Here's the breakdown:

I used the uuidtools gem to generate a universally unique id.

Gemfile.rb
gem 'uuidtools'

Then I created some helper methods in app/models to ensure that a UUID is generated and set whenever an ActiveRecord model is created or saved.

uuid_helper.rb

module UUIDHelper
  def self.append_features(base)
    base.before_create { |model| base.set_uuid_if_empty(model) }
    base.before_save { |model| base.set_uuid_if_empty(model) }

    def base.set_uuid_if_empty(model)
      if column_names.include?('uuid') and model.uuid.blank?
        model.uuid = UUIDTools::UUID.random_create().to_s
      end
    end
  end
end

Finally, I make sure that my models of interest have a uuid field of type string and set up my associations.

Thing.rb

class Thing < ActiveRecord::Base
  include UUIDHelper

  belongs_to :user, :primary_key => 'uuid', :foreign_key => 'owner'
end


User.rb

class User < ActiveRecord::Base
  include UUIDHelper

  has_many :thing, :primary_key => "uuid", :foreign_key => "owner"
end

I hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜