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.
精彩评论