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

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

问题描述

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



为了参考,这个问题是基于我之前的一个问题这里:在Rails中关联两个模型(用户和个人资料)



我正在建立一个拥有使用者模式和个人资料模式的应用程式。



这些模型使得:

- 在用户创建帐户后,他将自动发送到创建个人资料页面,并且他创建的个人资料仅与该特定用户相连。

- 只有拥有配置文件的用户可以编辑它。



我使用nifty_generators生成了用户模型。当用户点击提交创建帐户时,我将他重定向到新资料视图以创建配置文件。我通过编辑用户控制器中的重定向路径。用户控制器如下所示:

  def new 
@user = User.new
end

def create
@user = User.new(params [:user])
如果@ user.save
session [:user_id] = @ user.id
flash [:notice] =感谢您注册!您现在已经登录。
redirect_to new_user_profile_path(:user_id => @user)
else
render:action => 'new'
end
end

当我点击'submit'一个新用户,它现在发送我到以下url,这似乎是:localhost:3000 / users / 6 / profile / new。但它抛出以下异常:



中的NoMethodError ProfilesController#new当你没有不要期待!
评估
时出现错误nil.build


跟踪表明问题出现在配置文件控制器中,在New方法中。配置文件控制器如下所示:

  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])
如果@ profile.save
flash [:notice] ='配置文件已成功创建。 b $ b redirect_to(@profile)
else
flash [:notice] ='错误。发生错误。
render:action => new
end
end

此外,应用程序还会抛出异常当我尝试查看配置文件的索引页(目前没有配置文件,因为我不能超过用户创建步骤创建一个)。这是个例外:

ProfilesController中的ActiveRecord :: RecordNotFound#index

找不到ID为

的用户

这是日志告诉我的:


处理ProfilesController#index
[GET]参数:
{动作=>索引,
控制器=>个人资料}



ActiveRecord :: RecordNotFound没有ID):

app / controllers / profiles_controller.rb:5:in
`index'


为了给你的应用程序的其余细节,模型有以下关联:

配置文件归属_to:用户

用户有_one:profile



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



查看新的配置文件页面,抛出上面列出的第一个异常,我有这样:

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

在导致上述第二个异常的配置文件索引的视图中,我有:

 <%@ profiles.each do | profile | %> 
< div class =post>
< div class =left>
< p>商店:< / p>
< p>类别:< / p>
< / div>
< div class =right>
< p><%= h profile.name%>< / p>
< p><%= h profile.category%>< / p>
< / div>
< div class =bottom>
< p><%= link_to'转到个人资料',user_profile_path(@user,个人资料)%>< / p&
< p><%= link_to'Edit',edit_user_profile_path(@user,profile)%>< / p>
< p><%= link_to'Destroy',user_profile_path(@user,profile),:confirm => '你确定吗?',:method => :delete%>< / p>
< / div>





我花了几个小时试图跟踪问题自己作为一个学习练习,但在这一点上,我不知道如何解决这个问题。欣赏帮助!



更新:



jdl,根据您的要求:

/new.html.erb:

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



< 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%>必需
< / 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(截至8/20/09,美国东部标准时间晚8点)

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])
如果@ profile.save
flash [:notice] ='配置文件已成功创建'。
redirect_to(@profile)
else
flash [:notice] ='错误。发生错误。
render:action => new
end
end

def update
@profile = Profile.find(params [:id])
如果@ profile.update_attributes params [:profile])
flash [:notice] ='配置文件已成功更新'
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,索引页下面是抛出以下异常:

个人档案中的NoMethodError#index

显示第14行出现的应用程序/ views / profiles / index.html.erb:

未定义方法`name'for#

 < div id =posts> 
<%@ users.each do | profile | %>
< div class =post>
< div class =left>
< p>商店:< / p>
< p>类别:< / p>
< / div>
< div class =right>
< p><%= h profile.name%>< / p>
< p><%= h profile.category%>< / p>
< / div>
< div class =bottom>
< p><%= link_to'转到个人资料',user_profile_path(@user,个人资料)%>< / p&
< p><%= link_to'Edit',edit_user_profile_path(@user,profile)%>< / p>
< p><%= link_to'Destroy',user_profile_path(@user,profile),:confirm => '你确定吗?',:method => :delete%>< / p>
< / div>
< / div>


解决方案

错误告诉你, / p>

  @profile = @ user.profile.build 

@ user.profile是nil。



由于您尚未创建配置文件,这是有意义的。

  @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'转到个人资料',user_profile_path(user,user.profile)%>
<%end - %>
<%end - %>


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天全站免登陆