ActiveRecord:: RecordNotFound — не Мог найти Пользователя без идентификатора

Код дизайн

11
задан Community 23 May 2017 в 12:17
поделиться

3 ответа

Ошибка сообщает вам, что в этой строке:

@profile = @user.profile.build

@ user.profile равно нулю.

Поскольку вы еще не создали профиль, это имеет смысл. Вместо этого сделайте что-то вроде этого.

@profile = Profile.new(:user_id => @user.id)

Re: страница индекса вызывает исключение.

Вы определяете @users в вашем контроллере, а затем ссылаетесь на @user в ваших помощниках по пути. Кроме того, итерация по @users должна давать вам объекты User, а не Profile.

Похоже, вы пытаетесь использовать действие Profile # index для отображения списка пользователей. Это вроде нормально, не совсем в стиле REST. Однако я ожидал увидеть нечто подобное:

<% @users.each do |user| -%>
  <% unless user.profile.blank? -%>
    <%= h user.profile.name %>
    <%= h user.profile.category %>
    <%= link_to 'Go to profile', user_profile_path(user, user.profile) %>
  <% end -%>
<% end -%>
5
ответ дан 3 December 2019 в 11:21
поделиться

@jdl был правильным в том смысле, что в ProfilesController # new нет объекта @ user.profile, поэтому вызов @ user.profile.build вызовет исключение nil.

Вы можете исправить это, выполнив создание нового объекта Profile с помощью

@user.profile = Profile.new

. Позже, если @user будет сохранен, он вызовет @ user.profile и внешние ключи будут установлены соответствующим образом.

Также в вашем ProfilesController, действия #index и #show являются добрыми странно. Обычно действие #index возвращает «список объектов», а #show отображает только один объект, конкретный объект с идентификатором. Однако ваш #index возвращает очень конкретный объект, потому что он выполняет User.find с определенным идентификатором. Кроме того, поскольку у пользователя есть только один объект Profile, не имеет смысла загружать его объект Profile с помощью ORDER BY. Должен быть только один, поэтому порядок не требуется. Кроме того, спорный вопрос, нужно ли вам явно загружать объект профиля, поскольку вы можете просто получить к нему доступ через @ user.profile, а ActiveRecord загрузит его по запросу. Итак, ваш новый #index выглядит примерно как

def index
  @users = User.paginate(:all, :order = "created_at desc", :page => 1, :per_page => 10)
end

. Предполагается, что у вас есть плагин WillPaginate, но суть в том, что вы загружаете СПИСОК объектов, а не только один. На ваш взгляд, если вы выполняете итерацию по @users и вызываете .profile для элемента этого списка, ActiveRecord загружает связанный профиль на лету.

То же самое и для #show - нет необходимости явно загружать профиль.

def show
  @user = User.find(params[:user_id])
end
0
ответ дан 3 December 2019 в 11:21
поделиться

хм .. Я подумал, что когда у пользователя много профилей, вы можете использовать:

@user.profiles.build
@user.profiles.create

когда у пользователя один профиль, вы должны использовать:

@user.build_profile
@user.create_profile

Не уверен, проверьте API

1
ответ дан 3 December 2019 в 11:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: