Когда, если вообще, следует ли использовать идентификатор ассоциации напрямую? - PullRequest
3 голосов
/ 27 ноября 2010

Допустим, у меня есть модель User, модель Task, которая belongs_to :user, :has_one :event, имеет логический атрибут completed, и модель Event, которая создается при завершении задачи, также belongs_to :event.

В TaskObserver я заметил, что вместо

# app/controllers/task_observer.rb
class TaskObserver < ActiveRecord::Observer
def after_update(task)
  def after_update
    task.create_event(:user=>task.user) if task.completed?
  end
end

Я мог бы написать

task.create_event(:user_id=>task.user.id)

или даже

task.create_event(:user_id=>task.user_id)

Хотя первый способ кажется наиболее правильным, есть ли преимущества в использовании любого из последних вариантов?

Ответы [ 3 ]

2 голосов
/ 27 ноября 2010

Как сказал Берлингтон - здесь нет «правильного» или «неправильного» - возможно, следует учитывать производительность ...

В случае task.user.id, если пользователь не 'загруженный, вы совершаете путешествие в базу данных;в случае task.user_id вы не совершаете эту поездку туда и обратно ....

  • Примечание. Rails, вероятно, достаточно умен, чтобы заметить, что если вы просто получаете идентификатор из ассоциации, он можетпросто используйте task.user_id - но я не пошел на многое, чтобы подтвердить это.Было бы достаточно легко проверить это с помощью development.log ....
2 голосов
/ 27 ноября 2010

В Rails ассоциации могут быть назначены любым способом, ни "правильным", ни "неправильным", и это просто природа структуры.В моделях есть методы установки как для user_id, так и для user, поэтому вы можете использовать любой из них без каких-либо заметных различий.

Способ создания событий кажется мне немного странным.Кажется действительно странным, что задача будет принадлежать какому-либо событию, но событие создается только тогда, когда задача завершена.Это действительно так работает?

1 голос
/ 29 ноября 2010

В этом конкретном случае я пошел с task.create_event(:user_id=>task.user_id). Запустив:

$ rails c
ruby-1.8.7-p299 > ActiveRecord::Base.logger = Logger.new(STDOUT)
ruby-1.8.7-p299 > Task.where("user_id IS NOT NULL).user.id
...
User Load (1.2ms)  SELECT `users`.* FROM `users` WHERE (`users`.`id` = 103) LIMIT 1
=> 103

вы можете видеть, что Rails фактически загружает User из базы данных. Даже если он был кэширован, я не понимаю, почему я должен обрабатывать реальные объекты, если я просто копирую ссылку.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...