ActiveRecord::RecordNotFound -- 找不到没有 ID 的用户 [英] ActiveRecord::RecordNotFound -- Couldn't find User without an ID

查看:18
本文介绍了ActiveRecord::RecordNotFound -- 找不到没有 ID 的用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅问题底部的更新...

作为参考,这个问题是根据我之前在这里遇到的一个问题所做的一些修复演变而来的:在 Rails 中关联两个模型(用户和配置文件)

我正在构建一个具有用户模型和配置文件模型的应用.

我想将这些模型关联起来:
- 用户创建帐户后,会自动进入创建个人资料"页面,他创建的个人资料仅与该特定用户相关联.
- 只有拥有该配置文件的用户才能对其进行编辑.

我使用 nifty_generators 生成了用户模型.当用户点击提交创建帐户时,我将他重定向到新配置文件"视图以创建配置文件.我通过编辑用户控制器中的重定向路径来做到这一点.用户控制器看起来像这样:

def new@user = User.new结尾定义创建@user = User.new(params[:user])如果@user.savesession[:user_id] = @user.idflash[:notice] = "感谢您注册!您现在已登录."redirect_to new_user_profile_path(:user_id => @user)别的渲染:动作=>'新的'结尾结尾

当我单击提交"以创建新用户时,它现在将我发送到以下网址,这似乎是正确的:localhost:3000/users/6/profile/new.但它抛出以下异常:

<块引用>

NoMethodError 在ProfilesController#new 你有一个当你没想到它的时候,nil 对象!评估时发生错误nil.build

跟踪表明问题出在新方法中的配置文件控制器中.配置文件控制器看起来像这样:

def 索引@user = User.find(params[:user_id])@profile = @user.profile(:order => "created_at DESC")结尾高清秀@user = User.find(params[:user_id])@profile = @user.profile.find(params[:id])结尾定义新@user = User.find(params[:user_id])@profile = @user.profile.build结尾定义编辑@user = User.find(params[:user_id])@profile = @user.profile.find(params[:id])结尾定义创建@user = User.find(params[:user_id])@profile = @user.profile.build(params[:profile])如果@profile.saveflash[:notice] = '配置文件已成功创建.'重定向到(@profile)别的flash[:notice] = '错误.出问题了.'渲染:动作=>新的"结尾结尾

此外,当我尝试查看个人资料的索引页面时,该应用程序也会引发异常(目前没有个人资料,因为我无法通过用户创建步骤来创建个人资料).这是例外:
ActiveRecord::RecordNotFound in ProfilesController#index
找不到没有 ID 的用户

这就是日志告诉我的:

<块引用>

Processing ProfilesController#index[获取] 参数:{动作"=>索引",控制器"=>配置文件"}

ActiveRecord::RecordNotFound(不能查找没有 ID 的用户):
应用程序/控制器/profiles_controller.rb:5:in`索引'

为了向您提供应用程序的其余详细信息,模型具有以下关联:
个人资料属于 _to :user
用户有 _one :profile

我在 routes.rb 文件中有这个:map.resources :users, :has_one => :profile

在抛出上面列出的第一个异常的新个人资料页面的视图中,我有这个:

<% form_for([@user, @profile]) do |f|%><%= f.error_messages %>....<%结束%>

在抛出上面解释的第二个异常的配置文件索引的视图中,我有这个:

<% @profiles.each do |profile|%><div class="post"><div class="left"><p>商店:</p><p>类别:</p>

<div class="right"><p><%=h profile.name%</p><p><%=h profile.category%</p>

<div class="bottom"><p><%= link_to '转到个人资料', user_profile_path(@user, profile) %></p><p><%= link_to '编辑', edit_user_profile_path(@user, profile) %></p><p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm =>'你确定吗?', :method =>:删除%></p>

作为学习练习,我花了几个小时试图自己追踪问题,但此时我不知道如何解决这个问题.感谢您的帮助!

更新:

jdl,根据您的要求:
配置文件/new.html.erb:

<% form_for([@user, @profile]) do |f|%><%= f.error_messages %><div class="left"><p><%= f.label :name %><br/><%= f.text_field :name %> 必填</p><p><%= f.label :category %><br/><%= f.text_field :category %>必填</p><p><%= f.label :address1 %><br/><%= f.text_field :address1 %></p><p><%= f.label :address2 %><br/><%= f.text_field :address2 %></p><p><%= f.label :city%><br/><%= f.text_field :city %></p><p><%= f.label :state%><br/><%= f.text_field :state %></p><p><%= f.label :zip %><br/><%= f.text_field :zip %>必需</p><p><%= f.label :phone %><br/><%= f.text_field :phone %></p><p><%= f.label :email %><br/><%= f.text_field :email %></p>

<div class="right"><p><%= f.label :website %><br/><%= f.text_field :website %></p><p><%= f.label :description %><br/><%= f.text_area :描述%></p>

<p><%= f.submit '创建'%></p><%结束%>

routes.rb:
ActionController::Routing::Routes.draw 做 |map|
map.signup 'signup', :controller => 'users', :action => 'new'
map.logout '注销', :controller => 'sessions', :action => 'destroy'
map.login '登录', :controller => 'sessions', :action => 'new'
map.resources :sessions

 map.resources :users, :has_one =>:轮廓map.root :controller =>家"map.connect ':controller/:action/:id'map.connect ':controller/:action/:id.:format'结尾

配置文件控制器(截至 2009 年 8 月 20 日,美国东部标准时间晚上 8 点)
类 ProfilesController <应用控制器

 定义索引@users = User.all(:order => "created_at DESC")结尾高清秀@user = User.find(params[:user_id])结尾定义新@user.profile = Profile.new结尾定义编辑@user = User.find(params[:user_id])@profile = @user.profile.find(params[:id])结尾定义创建@user = User.find(params[:user_id])@profile = @user.profile.build(params[:profile])如果@profile.saveflash[:notice] = '配置文件已成功创建.'重定向到(@profile)别的flash[:notice] = '错误.出问题了.'渲染:动作=>新的"结尾结尾定义更新@profile = Profile.find(params[:id])如果@profile.update_attributes(params[:profile])flash[:notice] = '配置文件已成功更新.'重定向到(@profile)别的渲染:动作=>编辑"结尾结尾销毁@profile = Profile.find(params[:id])@profile.destroy重定向到(profiles_url)结尾结尾

Cody,下面的索引页抛出以下异常:
配置文件中没有方法错误#index
显示第 14 行引发的 app/views/profiles/index.html.erb:
#

的未定义方法名称"

 

<% @users.each 做 |profile|%><div class="post"><div class="left"><p>商店:</p><p>类别:</p>

<div class="right"><p><%=h profile.name%</p><p><%=h profile.category%</p>

<div class="bottom"><p><%= link_to '转到个人资料', user_profile_path(@user, profile) %></p><p><%= link_to '编辑', edit_user_profile_path(@user, profile) %></p><p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm =>'你确定吗?', :method =>:删除%></p>

解决方案

错误告诉你在这一行:

@profile = @user.profile.build

@user.profile 为零.

由于您还没有创建配置文件,这是有道理的.相反,去做这样的事情.

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

<小时>

回复:索引页抛出异常.

您在控制器中定义@users,然后在路径助手中引用@user.此外,迭代@users 应该给你 User 对象,而不是 Profile 对象.

您似乎正在尝试使用 Profile#index 操作来显示用户列表.以一种不太纯粹的 REST 方式,这还算可以.但是,我希望看到更多类似的东西.

<% @users.each do |user|-%><% 除非 user.profile.blank?-%><%= h user.profile.name %><%= h user.profile.category %><%= link_to '转到个人资料', user_profile_path(user, user.profile) %><%结束-%><%结束-%>

Please see UPDATES at the bottom of the question...

For reference, this problem evolved out of some fixes I made based on a previous problem I was having here: Associating Two Models in Rails (user and profile)

I'm building an app that has a user model and a profile model.

I want to associate these models such that:
- After the user creates an account, he is automatically sent to the "create profile" page, and the profile he creates is connected to only that particular user.
- Only the user who owns the profile can edit it.

I generated the user model using nifty_generators. When the user hits submit for the account creation, I redirect him to the "new profile" view to create a profile. I did this by editing the redirect path in the user controller. The user controller looks like this:

def new
  @user = User.new
end

def create
  @user = User.new(params[:user])
  if @user.save
    session[:user_id] = @user.id
    flash[:notice] = "Thank you for signing up! You are now logged in."
    redirect_to new_user_profile_path(:user_id => @user)
  else
    render :action => 'new'
  end
end

When I click 'submit' to create a new user, it now sends me to the following url, which seems right: localhost:3000/users/6/profile/new. But it throws the following exception:

NoMethodError in ProfilesController#new You have a nil object when you didn't expect it! The error occurred while evaluating nil.build

The trace indicates that the problem is in the profiles controller, in the New method. The profiles controller looks like this:

def index
  @user = User.find(params[:user_id])
  @profile = @user.profile(:order => "created_at DESC")
end

def show
  @user = User.find(params[:user_id])
  @profile = @user.profile.find(params[:id])
end

def new
  @user = User.find(params[:user_id])
  @profile = @user.profile.build
end

def edit
  @user = User.find(params[:user_id])
  @profile = @user.profile.find(params[:id])
end

def create
  @user = User.find(params[:user_id])
  @profile = @user.profile.build(params[:profile])
    if @profile.save
      flash[:notice] = 'Profile was successfully created.'
      redirect_to(@profile)
    else
      flash[:notice] = 'Error.  Something went wrong.'
      render :action => "new"
    end
end

Additionally, the app also throws an exception when I try to view the index page of the profiles (there are currently no profiles because I can't get past the user creation step to create one). This is the exception:
ActiveRecord::RecordNotFound in ProfilesController#index
Couldn't find User without an ID

This is what the log is telling me:

Processing ProfilesController#index [GET] Parameters: {"action"=>"index", "controller"=>"profiles"}

ActiveRecord::RecordNotFound (Couldn't find User without an ID):
app/controllers/profiles_controller.rb:5:in `index'

To give you the rest of the details on the app, the models have the following associations:
Profile belongs _to :user
User has _one :profile

I have this in the routes.rb file: map.resources :users, :has_one => :profile

In the view for the new profile page that's throwing the first exception listed above, I have this:

<% form_for([@user, @profile]) do |f| %>
  <%= f.error_messages %>
....
<% end %>  

In the view for the profile index that's throwing the second exception explained above, I have this:

<% @profiles.each do |profile| %>
<div class="post">
    <div class="left">
        <p>Store: </p>
        <p>Category: </p>
    </div>
    <div class="right">
        <p><%=h profile.name %></p>
        <p><%=h profile.category %></p>
    </div>
    <div class="bottom">
        <p><%= link_to 'Go to profile', user_profile_path(@user, profile) %></p>
        <p><%= link_to 'Edit', edit_user_profile_path(@user, profile) %></p>
        <p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm => 'Are you sure?', :method => :delete %></p>
    </div>

I've spent hours trying to track down the problem myself as a learning exercise, but at this point I have no idea how to fix this. Appreciate the help!

UPDATE:

jdl, per your request:
profiles/new.html.erb:

<% form_for([@user, @profile]) do |f| %>
  <%= f.error_messages %>



<div class="left">
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>required
  </p>
    <p>
    <%= f.label :category %><br />
    <%= f.text_field :category %>required
  </p>
  <p>
    <%= f.label :address1 %><br />
    <%= f.text_field :address1 %>
  </p>
  <p>
    <%= f.label :address2 %><br />
    <%= f.text_field :address2 %>
  </p>
  <p>
    <%= f.label :city %><br />
    <%= f.text_field :city %>
  </p>
  <p>
    <%= f.label :state %><br />
    <%= f.text_field :state %>
  </p>
  <p>
    <%= f.label :zip %><br />
    <%= f.text_field :zip %>required
  </p>
  <p>
    <%= f.label :phone %><br />
    <%= f.text_field :phone %>
  </p>
  <p>
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </p>

  </div>

  <div class="right">
  <p>
    <%= f.label :website %><br />
    <%= f.text_field :website %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description %>
  </p>
  </div>

  <p>
    <%= f.submit 'Create' %>
  </p>
    <% end %> 

routes.rb:
ActionController::Routing::Routes.draw do |map|
map.signup 'signup', :controller => 'users', :action => 'new'
map.logout 'logout', :controller => 'sessions', :action => 'destroy'
map.login 'login', :controller => 'sessions', :action => 'new'
map.resources :sessions

  map.resources :users, :has_one => :profile  

  map.root :controller => "home"   
  map.connect ':controller/:action/:id'  
  map.connect ':controller/:action/:id.:format'  
end  

PROFILES CONTROLLER (as of 8/20/09, 8pm EST)
class ProfilesController < ApplicationController

  def index
    @users = User.all(:order => "created_at DESC")
  end

  def show
    @user = User.find(params[:user_id])
  end

  def new
    @user.profile = Profile.new
  end

  def edit
    @user = User.find(params[:user_id])
    @profile = @user.profile.find(params[:id])
  end

  def create
    @user = User.find(params[:user_id])
    @profile = @user.profile.build(params[:profile])
      if @profile.save
        flash[:notice] = 'Profile was successfully created.'
        redirect_to(@profile)
      else
        flash[:notice] = 'Error.  Something went wrong.'
        render :action => "new"
      end
  end

  def update
    @profile = Profile.find(params[:id])
      if @profile.update_attributes(params[:profile])
        flash[:notice] = 'Profile was successfully updated.'
        redirect_to(@profile)
      else
        render :action => "edit"
      end
  end

  def destroy
    @profile = Profile.find(params[:id])
    @profile.destroy
      redirect_to(profiles_url)
  end
end

Cody, the index page below is throwing the following exception:
NoMethodError in Profiles#index
Showing app/views/profiles/index.html.erb where line #14 raised:
undefined method `name' for #

    <div id="posts">
<% @users.each do |profile| %>
    <div class="post">
        <div class="left">
            <p>Store: </p>
            <p>Category: </p>
        </div>
        <div class="right">
            <p><%=h profile.name %></p>
            <p><%=h profile.category %></p>
        </div>
        <div class="bottom">
            <p><%= link_to 'Go to profile', user_profile_path(@user, profile) %></p>
            <p><%= link_to 'Edit', edit_user_profile_path(@user, profile) %></p>
            <p><%= link_to 'Destroy', user_profile_path(@user, profile), :confirm => 'Are you sure?', :method => :delete %></p>
        </div>
  </div> 

解决方案

The error is telling you that in this line:

@profile = @user.profile.build

@user.profile is nil.

Since you haven't created the profile yet, this makes sense. Instead, go for something like this.

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


Re: The index page throwing an exception.

You are defining @users in your controller, and then referencing @user in your path helpers. Also, iterating over @users should give you User objects, not Profile objects.

It looks like you're trying to use the Profile#index action to show a list of users. That's kind-of OK, in a not-quite-pure-REST way. However, I would expect to see something more like this.

<% @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 -%>

这篇关于ActiveRecord::RecordNotFound -- 找不到没有 ID 的用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆