尝试访问视图时出现未定义的方法错误

时间:2014-08-11 18:02:30

标签: ruby-on-rails ruby

我正在尝试学习Rails。我正在关注一本书,但我一直收到以下错误:

undefined method `first_name' for nil:NilClass error

以下是代码。

我不明白为什么@user.first_name无法覆盖用户/展示视图。 有点帮助不会是坏事。

控制器:

class UsersController < ApplicationController
    def new
        @user = User.new
    end
    def create 
        @user = User.new(params.require(:user).permit!)
        if @user.save
            flash[:notice] = "Welcome"
            redirect_to @user
        else
            render :new
        end
    end
    private
    def user_params
        params.require(:user).permit!
    end
    def show
        @user = User.find(params[:id])
        render layout: 'profile'
    end
end

模型:

class User < ActiveRecord::Base
        has_secure_password
        validates :username,   presence: true,
                               uniqueness: {case_sensitive: false},
                               length: {in: 4..12},
                               format: {with: /\A[a-zA-Z][a-zA-Z0-9_-]*\Z/}

        validates :first_name, presence: true
        validates :last_name,  presence: true
        validates :email,      presence: true,
                               uniqueness: {case_sensitive: false},
                               email: true
        validates :password,   presence: true,
                               length: {minimum: 6}


    end

查看:

<div class="row">
<div class="large-12 columns">
<div class="large-2 columns">
<img src="http://placehold.it/160x160" class="profile-image" alt="">
</div>
<div class="large-10 columns">
<p><%= "#{@user.first_name}" %></p>
<div class="button-bar">
<ul class="button-group-radius">
<li><%= link_to "Subject", user_path(@user, page: 'subjects'), class: 'small button secondary' %></li>
<li><%= link_to "Comments", user_path(@user, sayfa: 'comments'), class: 'small button secondary' %></li>
<li><%= link_to "Edit My Profile", edit_user_path(@user), class: 'small button secondary' %></li>
<li><%= link_to "Delete My Account", @user, class: 'small button alert', method: :delete %></li>
</ul>
</div>
</div>
<div class="large-12 colums">
Subject..
</div>
</div>
</div>

3 个答案:

答案 0 :(得分:1)

您需要将show操作移出private范围:

class UsersController < ApplicationController
  ...
  ...
  def show
    @user = User.find(params[:id])
    render layout: 'profile'
  end

  private
  def user_params
    params.require(:user).permit!
  end
end

<强>改进:

你可以写

<p><%= @user.first_name %></p>

而不是

<p><%= "#{@user.first_name}" %></p>

答案 1 :(得分:1)

您可以在代码中修复两件事。首先,您需要将“show”操作拉出私有部分,因此整个应用程序都可以看到它。你在“私人”一词之后提出的每一种方法都是私人的,而不仅仅是下一种方法。如果你将show动作保留在那里,则无法找到它。

第二件事是你有一个名为user_params的私有方法,它已经设置了强大的参数,所以你可以通过重构user_párams的参数来保持“创建”动作更简单,因为它们返回相同的东西。在Ruby中,其中一个支柱是DRY - 不要重复自己。你的控制器会是这样的:

 def new
    @user = User.new
end
def create 
    @user = User.new(user_params)
    if @user.save
        flash[:notice] = "Welcome"
        redirect_to @user
    else
        render :new
    end
end
def show
    @user = User.find(params[:id])
    render layout: 'profile'
end
private
def user_params
    params.require(:user).permit!
end

答案 2 :(得分:0)

将您的show方法向上移动到private关键字上方,它应该可以正常工作。

原因是默认情况下,rails会渲染路由关联视图。

例如:

resources :users, only: :index

加上以下控制器

class UsersController < ApplicationController
end

并呼叫/用户

即使您没有看到它,也会自动呈现用户/索引视图。当您自己编写动作方法时,您实际上会覆盖默认行为。

在你的情况下,你有一个私人表演方法,这意味着你在调用show /:id路线时无法访问它。它回退到默认行为。只有公共方法可以作为操作调用。

您应该阅读the ActionController guide以了解发生了什么。