这是我的代码:
//在swimmer.rb(模型)中:
belongs_to :user
//在user.rb(model)中:
has_one :swimmer, :dependent => :destroy
accepts_nested_attributes_for :swimmer, :allow_destroy => true
attr_accessible :swimmer_attributes
//在swimmers_controller.rb中:
def profile
@swimmer = Swimmer.find_by_user_id(current_user)
@swimmer_nickname = @swimmer.nickname
@swimmer_gender = @swimmer.gender
@title = "Swimmer Profile for #{@current_user.email}"
end
//在profile.html.erb中(在游泳者视图文件夹中)
<% if @swimmer %>
<h3><%= @title %></h3>
<p>Nickname: <%= @swimmer_nickname %></p>
<p>Gender: <%= @swimmer_gender %></p>
<% else %>
<h3>No Swimmer Profile for<%= current_user.email %></h3>
<% end %>
如果一个游泳者对象的user_id与游泳者#controller方法中的@swimmer实例变量相匹配,因为有一个登录用户(使用Devise gem)并且已经为该用户创建了一个游泳者,那么该个人资料视图按预期工作。如果没有,页面显示错误:
NoMethodError (undefined method `nickname' for nil:NilClass):
app/controllers/swimmers_controller.rb:66:in `profile'
但是由于配置文件视图具有if / else条件,我希望缺少与登录用户关联的swimmer对象来强制视图显示else内容。显然,“Swimmer.find_by_user_id(current_user)”方法正在NilClass中创建一个nil对象。我如何得到它,以便它不会创建任何东西,从而带来其他条件?
回购位于https://github.com/drollwit/vst2/tree/ver2。这是一个练习,而不是一个真正的项目。这里可能有一个简单的答案,但我无法弄明白(仍在学习Rails基础知识)。任何帮助将不胜感激。
答案 0 :(得分:1)
问题不在于视图,而是您的个人资料方法:
def profile
@swimmer = Swimmer.find_by_user_id(current_user)
@swimmer_nickname = @swimmer.nickname
@swimmer_gender = @swimmer.gender
@title = "Swimmer Profile for #{@current_user.email}"
end
如果没有找到游泳者,则@swimmer为零,并且以下行失败,因为您在nil上调用方法'nickname'。
一个简单的解决方法如下:
def profile
@swimmer = Swimmer.find_by_user_id(current_user)
@swimmer_nickname = @swimmer.try(:nickname)
@swimmer_gender = @swimmer.try(:gender)
@title = "Swimmer Profile for #{@current_user.email}"
end
如果@swimmer不存在,@ simmwer_nickname和@swimmer_gender将设置为nil。请参阅http://api.rubyonrails.org/classes/NilClass.html#method-i-try。
就个人而言,我不会像这样在控制器中分配这些额外的实例变量。我会把它移到视图中,或者也许是帮助者。
答案 1 :(得分:1)
错误原因存在于以下代码行中。
@swimmer = Swimmer.find_by_user_id(current_user)
它永远不会根据user_id.Because
找到Swimmerfind_by_user_id
需要ID.Try
@swimmer = Swimmer.find_by_user_id(current_user.id)
您将获得游泳者对象,然后不会发生错误。
您可以通过
改进查看文件<% if @swimmer %>
<h3><%= "Swimmer Profile for #{@current_user.email}" %></h3>
<p>Nickname: <%= @swimmer.nickname %></p>
<p>Gender: <%= @swimmer.gender %></p>
<% else %>
<h3>No Swimmer Profile for<%= current_user.email %></h3>
<% end %>
这将减少控制器的以下代码行。
@swimmer_nickname = @swimmer.nickname
@swimmer_gender = @swimmer.gender
@title = "Swimmer Profile for #{@current_user.email}"