Как заставить две разные модели ActiveResource использовать два разных объекта соединения? - PullRequest
0 голосов
/ 16 марта 2011

Оказывается, соединение между моделями ActiveResource является общим. Таким образом, если вы установите формат в одной модели, останется отличным от формата в других моделях. Однако, если вы вызываете метод .connection.format на двух отдельных моделях, этот формат изменяется каждый раз, когда вы устанавливаете новый формат. Таким образом, если Profile был загружен в секунду в формате :json, то .connection.format для обеих моделей превращается в ActiveResource::Formats::JsonFormat

Мой оригинальный вопрос был совершенно другим (я не до конца понял, что происходит) - вы можете посмотреть историю изменений, чтобы увидеть оригинальную версию. Надеюсь, я получу больше ответов ...

Доказательство:

class Location < ActiveResource::Base
  self.format = :xml
end

class Profile < ActiveResource::Base
  self.format = :json
end

Тогда в rails console ...

>> Location.format
=> ActiveResource::Formats::XmlFormat
>> Location.connection.format
=> ActiveResource::Formats::XmlFormat

Пока все хорошо ... модель Location и ее соединение имеют правильный формат.

>> Profile.format
=> ActiveResource::Formats::JsonFormat

выглядит нормально, это формат для Profile, который я хочу.

>> Location.format
=> ActiveResource::Formats::XmlFormat

Хорошо ... Location.format остается тем же после загрузки модели профиля. Примечание : эти модели загружаются отложенным образом, поэтому их файлы и код не включаются, пока вы не попытаетесь вызвать имя класса.

>> Location.connection.format
=> ActiveResource::Formats::JsonFormat

И тут начинается проблема. После того, как мы позвонили в модель профиля, она обнаружила Location.connection.format

>> Profile.connection.format
=> ActiveResource::Formats::JsonFormat

Форматы не должны быть одинаковыми. Это приводит к тому, что синтаксический анализ полностью прерывается, когда вы вызываете что-то вроде Location.find (: all,: from => "/something.xml") - он пытается проанализировать xml как json

Полагаю, мой вопрос сейчас - как мне разделить две связи? (Или иным образом решить эту проблему)

Изменить, чтобы добавить этот тест в консоль:

>> Location.connection == Profile.connection
=> true

1 Ответ

1 голос
/ 16 марта 2011

Это ... похоже на ошибку.

Я искал ActiveResource исходный код.Когда вы вызываете метод format= в вашем классе ARes, он записывает формат в connection.format.

Метод connection в этом контексте захватит @@connection, если он определен, в противном случае он вызовет superclass.connection.В нашем случае superclass - это ActiveResource::Base.Как вы можете догадаться, @@connection на моделях Location или Profile не определено.Он будет установлен, если вы вызовете self.site= для вашего класса, и в этом случае метод self.format= установит формат для вашей классовой версии объекта connection.

В моем случае у меня нет причин использовать другую переменную сайта для разных моделей ActiveResource, просто другой формат возврата.По этой причине я устанавливал ActiveResource::Base.site = "myresource.local" в разработке (и соответствующий в файле env production.rb).

Итак, мое решение этой проблемы?

class Location < ActiveResource::Base
  self.site = self.site
  self.format = :xml
end

Да,self.site = self.site заставляет класс использовать свой собственный объект соединения.Почему-то я чувствую, что self.format = также должен ...

Пока не собираюсь принимать этот ответ, потому что он выглядит как хак и / или ошибка, но вот как я решил это сейчас, и появляется на работу.

Надеюсь, у кого-то еще есть мысли по этому поводу?Не похоже, чтобы очень многие использовали ActiveResource, но мы используем его ежедневно, и я сталкивался с этим раньше.

...