2015-04-20 4 views
0

Я подключаюсь к одной из баз данных SQL Server моей компании и пытаюсь настроить ActiveRecord, чтобы я мог относиться к ним так же, как к объектам Rails.Могу ли я сделать ассоциацию belongs_to использовать загрузку по умолчанию?

У меня есть эти две модели:

class Change < ActiveRecord::Base 
    belongs_to :affected_contact, class_name: "Contact" 
end 

class Contact 
    # Contact's primary key is a binary UUID; I can't change this 
end 

Я пытаюсь получить пораженный контакт одного конкретного изменения. Обычно это будет простой случай, но:

Change.first.affected_contact 
    Change Load (52.6ms) EXEC sp_executesql N'SELECT TOP (1) [chg].* FROM [chg] ORDER BY [chg].[id] ASC' 
    Contact Load (28.0ms) EXEC sp_executesql N'SELECT TOP (1) [ca_contact].* FROM [ca_contact] WHERE [ca_contact].[contact_uuid] = @0', N'@0 binary', @0 = 0xfcf9a8ac6381aa4386c9b10ee382e10b [["contact_uuid", "<16 bytes of binary data>"]] 
=> nil 

... это не то, что я хочу! И все же, если я готов нагружать объединение первых, это работает:

Change.eager_load(:affected_contact).first.affected_contact 
    SQL (34.4ms) EXEC sp_executesql N'SELECT TOP (1) holy_crap_theres_a_lot_of_columns FROM [chg] LEFT OUTER JOIN [ca_contact] ON [ca_contact].[contact_uuid] = [chg].[affected_contact] ORDER BY [chg].[id] ASC' 
=> #<Contact contact_uuid: "\xFC\xF9\xA8\xACc\x81\xAAC\x86\xC9\xB1\x0E\xE3\x82\xE1\v", ... > 

В самом деле, если я заставляю согласование должно произойти в пункте JOIN в любом случае, это будет работать, но belongs_to кажется использовать WHERE, а nil - лучший ответ, который я могу получить (много времени, есть ошибки преобразования между строкой и ее двоичным типом).

Есть ли способ обеспечить надежную загрузку через предложение JOIN по умолчанию в ассоциации belongs_to?

ответ

0

Я обнаружил, что #find_by_contact_uuid (contact_uuid является первичным ключом) работал, где #find не по какой-то причине. Это привело к тому, что это было реализовано.

я в конечном итоге существенно переписывания методы ассоциации, что активные поставки Запись:

module AssociationMethods 
    def self.included(base) 
    base.reflect_on_all_associations(:belong_to).each do |a| 
     define_method a.name do 
     # #find_by_<uuid_pk> seems to work where #find doesn't 
     a.klass.send "find_by_#{a.association_primary_key}", self[a.foreign_key] 
     end 
    end 

    base.reflect_on_all_associations(:has_many).each do |a| 
     define_method a.name do 
     a.klass.where(a.foreign_key => self.send(a.association_primary_key)) 
     end 
    end 
    end 
end 

class Contact 
    has_many :changes, foreign_key: :affected_contact_id 
    include AssociationMethods # include *after* all associations are defined 
end 

class Change 
    belongs_to :affected_contact, class_name: 'Contact' 
    include AssociationMethods 
end 

Он не покрывает все что активные поставки записи при настройке ассоциаций, но это, кажется, сделать трюк ,

-1

Использование includes должно решить вашу проблему. Это связано с тем, что includes будет preload или eager_load в зависимости от ваших других условий.

read more here

+0

Это не моя проблема. Я _need_ использовал запрос 'JOIN' (' eager_load'), потому что UUID слишком сложно передать в предложениях WHERE. Но как я могу определить ассоциацию 'belongs_to', чтобы это сделать? Я хочу сказать «change.affected_contact», а не «Change.where (id: change.id) .eager_load (: affected_contact) .first.affected_contact'. – PJSCopeland

+0

Привет Sameera. Я считаю [более 50 обычаев строительства «coz»] (https://stackoverflow.com/search?q=user%3A319702+coz) в ваших сообщениях. Если вы имеете в виду «потому что», вы бы это использовали? У нас здесь много людей, чей родной язык не английский, и я боюсь, что мы учим их, что мерзость SMS - это настоящие слова. – halfer

 Смежные вопросы

  • Нет связанных вопросов^_^