2016-04-19 3 views
0

Являясь новым для Ruby on Rails и наблюдал во время учебного пособия, что новое сообщение было создано как показано ниже.Rails: Почему мы должны использовать текущего пользователя для создания сообщения?

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

В модели сообщений, мы можем просто создать переменную user_id и сохраните в нем current_user.id, и таким образом мы знаем, какое сообщение было создано пользователем.

Что является причиной использования current_user.build

def new 
    @message = current_user.messages.build 
end 

def create 
    @message = current_user.messages.build(message_params) 
    if @message.save 
     redirect_to root_path 
    else 
     render 'new' 
    end 
end 
+0

Опубликовать схему для вашей модели сообщений. Должен иметь атрибут: user_id в нем, который будет автоматически заполняться оператором сборки. –

+0

Да, существует user_id как целое число. Точно так же Rail автоматически соглашается с тем, что, поскольку пользователь является моделью, поэтому в Message, должен быть user_id? Как в _id согласно конвенции? – Tahseen

+0

Точно. Если user_id находится в таблице, тогда, когда вы делаете current_user.messages.build, он автоматически заполнит его. –

ответ

2

Это

@message = current_user.messages.build 

выглядит, как это было бы то же самое, по логике вещей, как делать это:

@message = Message.new(:user_id => current_user.id) 

и это почти так, с одним важным исключением. Если вы уже определили current_user и вызвали .messages на этом объекте, рельсы будут искать связанные сообщения и кэшировать их за эффективность, так что если вы делаете current_user.messages снова в том же самом действии, вам не нужно их снова искать , Если вы затем сделаете @message = Message.create(:user_id => current_user.id), вы внесли ассоциацию в базу данных, но объект current_user в памяти не знает об изменении, и поэтому, если вы делаете current_user.messages, вы не можете получить новое сообщение.

С другой стороны, делая current_user.messages.build обновляет кэшированные ассоциацию в процессе, так current_user.messagesбудет включить новое сообщение.

+0

Но как насчет ситуации, когда есть модель комментариев, которая в основном отвечает на модель сообщений. Как и в людях, прочитайте сообщение и ответьте на него. В этом случае мы создаем @comment = message.comments.build вот так? – Tahseen

+0

Просто одно небольшое добавление: вызов 'current_user.messages.build' не будет инициировать запрос базы данных для других сообщений. Это сначала произойдет, когда вы действительно используете сообщения (например, вызовите метод массива на нем) – jack

+0

@Tahseen да, вы могли бы создать такой комментарий. –

0

При использовании current_user.messages.build, он автоматически назначает user_id для объекта. Но в случае Message.new вам необходимо передать явно user_id. например, Message.new(:user_id=>current_user.id).

1

Существует одно важное различие между этими двумя линиями:

current_user.messages.build 

и

Message.new(:user_id => current_user.id) 

На первой строке, вы просто не должны знать, как отношение строится и как настроены клавиши. Что, если однажды вы захотите изменить его на отношения «многие ко многим»? Или если вы хотите добавить условия (например, deleted_at => nil). Единственное место, где вы можете установить свои отношения, находится внутри ваших моделей. И должны быть только редкие случаи, когда вам придется ссылаться на детали из этих отношений за пределами ваших моделей.

+0

Я думаю, что это, вероятно, главная причина, по которой она предпочтительнее по соглашению, а не мои предложения о «аккуратности» и «обновлении кэшированного прокси-сервера "(оба из которых являются истинными, но, возможно, вторичными). –

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