Что «первый» делает в Ruby и Rails? - PullRequest
2 голосов
/ 21 января 2012

Я реализовал функцию, которая позволяет пользователям устанавливать фотографии профиля по умолчанию и фотографии обложки фотоальбома.

В моей базе данных есть следующие таблицы:

  • Пользователь (и) -имеет один профиль, имеет много Фотоальбомов
  • Профили - принадлежит пользователю
  • Фотоальбом (ы) - принадлежит пользователю, имеет много фотографий
  • Фото (и) -принадлежит PhotoAlbum

Действие для установки фотографии профиля по умолчанию:

def set_default_profile_photo
  photo = Profile.find_by_user_id(current_user.id)
  photo.photo_id = params[:photo_id]
  photo.save
  redirect_to :back
  flash[:success] = "Default photo set!"
end

Это прекрасно работает.

Установка моей фотографии альбома по умолчанию была немного сложнее:

def set_default_album_photo
  photo = PhotoAlbum.where(:id => Photo.where(:id => params[:photo_id]).first.photo_album_id)
  photo.first.photo_id = params[:photo_id]
  photo.first.save
  redirect_to :back
  flash[:success] = "Default album photo set!"
end

Это действие не сработало:

def set_default_album_photo
  photo = PhotoAlbum.where(:id => Photo.where(:id => params[:photo_id]).first.photo_album_id)
  photo.photo_id = params[:photo_id]
  photo.save
  redirect_to :back
  flash[:success] = "Default album photo set!"
end

Я заработал, и неопределенная ошибка photo_id method исчезла, но это произошло после изменения этихстроки от:

photo.photo_id = params[:photo_id]
photo.save

до:

photo.first.photo_id = params[:photo_id]
photo.first.save

Я не уверен, что происходит, и почему это изменение заставило вещи работать, и хочу понять, что происходит.

Ответы [ 2 ]

7 голосов
/ 21 января 2012

У меня нет возможности комментировать, поэтому я не смог прокомментировать вышеприведенный пост, но я должен отметить:

Foo.where(:id => X).first НЕ совпадает с Foo.find(X).Foo.find(X) вызовет исключение, если нет записи с id = X, а другая просто вернет ноль.

6 голосов
/ 21 января 2012

find_by_foo возвращает один объект.where возвращает коллекцию (отношение).Очевидно, что вы не можете сделать photo.photo_id, когда photo является коллекцией Photo объектов (вместо одного Photo).

first возвращает первый объект коллекции.Поэтому, вызывая first для коллекции, возвращаемой where, вы получаете один объект Photo, с которым вы можете работать.

Обратите внимание, что Foo.where(:id => bla).first совпадает с Foo.find(bla), поэтому выможно просто использовать

PhotoAlbum.find( Photo.find(params[:photo_id]).photo_album_id )

вместо

PhotoAlbum.where(:id => Photo.where(:id => params[:photo_id]).first.photo_album_id).first
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...