2013-11-21 2 views
1

«Прежде всего, тот факт, что я даже задаю этот вопрос, подразумевает, что я сознательно не хочу (строго) подчиняться закону Деметры.рельсы ассоциации и идентичность объекта: сохранение идентичности объекта посредством серии изменений

Так как когда-то (вероятно, рельсы 3?) Со ссылкой на model.association.first результаты в новом объекте каждый раз, если вы не используете .to_a на ассоциации:

campaign.campaign_shirts.first.to_s 
=> "#<CampaignShirt:0x007fdd02c7fd58>" 
campaign.campaign_shirts.first.to_s 
=> "#<CampaignShirt:0x007fdd02ca6318>" 
c.campaign_shirts.to_a.first.to_s 
=> "#<CampaignShirt:0x007fdd02d13170>" 
c.campaign_shirts.to_a.first.to_s 
=> "#<CampaignShirt:0x007fdd02d13170>" 

Я работал на нескольких Rails 3/4 приложений без даже замечая это, вероятно, потому, что я стараюсь уважать Деметру настолько, насколько это практично.

В этом случае я хочу, чтобы Кампания контролировалась, потому что это большой государственный автомат, в котором многие из его изменений состояния связаны с транзакционными координирующими изменениями в себе и с различными дочерними объектами.

Есть ли способ заморозить массивы ассоциаций при создании и/или выборке времени?

EDIT: Я заметил почти сразу, что они заморожены, когда вы используете Campaign.includes(...).find, что я делаю в своем приложении. Однако у меня все еще есть проблема в спецификациях, где объекты - это фабрики, созданные FactoryGirl. Есть ли способ сказать «заморозить все ассоциации на этом объекте» или мне нужно позвонить .to_a по каждому из них?

EDIT 2: У меня все еще есть проблема, когда я ссылаюсь на кампанию через belongs_to на пользователя. (это казалось отдельным вопросом, поэтому я asked it here). РЕДАКТИРОВАТЬ 3: проблема с include_to включает расширение, было просто синтаксисом, поэтому я удаляю детали этого.

Итак, моя оставшаяся проблема заключается в том, чтобы заставить User.selected_campaign действовать так, как в моем приложении, когда он создан FactoryGirl. Я собираюсь попробовать только сделать .reload в начале каждого спецификатора, что должно вызвать включение расширений за счет некоторой производительности спекуляции.

ответ

2

Я не знаю (gory) деталей вашей установки, но что, если вы просто memoizefirst на объекте кампании?

def Campaign 
    def first_campaign_shirt 
    @first_campaign_shirt ||= campaign_shirts.first 
    end 
end 

Я так думаю, что вы снова подчиняетесь Закону Деметры? Но это может раздражать, если вам нужно больше геттеров, а не только first_shirt. Поэтому рассмотрите это просто предложение, которое не будет вписываться в поле комментариев. :)

+0

Я ценю предложение, но, если возможно, я хотел бы избежать добавления заметок или других изменений в вещи, которые Rails ожидает контролировать, потому что это делает жизнь трудной в долгосрочной перспективе для таких программистов, как я, у которых очень короткий memory spa –

+0

также, я использовал только первый пример, чтобы проиллюстрировать изменение идентификатора объекта. Мне нужно, чтобы все объекты были заморожены. Я должен буду memoize всей ассоциации, которые рельсы уже делают, если вы вызываете .to_a на ней или если ассоциация была предварительно выбрана предложением include (..). –

0

Все мои случаи использования в приложении были решены путем тщательного выбора, куда добавлять(), в ассоциации и области.

Я только смог решить проблему заводской девушки, вызвав перезагрузку объекта фабрики после ее создания.

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