我正在尝试学习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>
答案 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以了解发生了什么。