Rails Nil方法问题

时间:2013-07-08 23:11:42

标签: ruby-on-rails ruby

我一直在借用我的rails 3应用程序上的旧ruby中的一些代码来获取新的rails 4应用程序。该代码适用于旧网站,但在新网站上却没有。

这是我的routes.rb:

scope ':username' do
  resources :recipes
end
get "/:username" => "recipes#index"

这是我的控制器索引:

def index
   @user = User.find_by_username params[:username]
   @recipes = Recipe.all
end

和我的观点:

<% @recipes.each do |recipe| %>
  <tr>
    <td><%= recipe.name %></td>
    <td><%= link_to recipe.name, recipe_path(username: @user.username, id: recipe.id) %></td>
    <td><%= link_to 'Edit', edit_recipe_path(recipe) %></td>
    <td><%= link_to 'Destroy', recipe, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

但弹出错误:

undefined method `username' for nil:NilClass

但是当前用户的用户名设置为test所以它不是nil,错误不应该弹出。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

当你的变量可能是零时,你应该处理它们为零的情况,除非你明确希望它在这些情况下失败。

当没有找到记录时,动态find_by方法返回nil。因此,正如alfonso指出的那样,你得到@user的空值。

在这个特定的例子中,我会质疑你是如何使用用户名参数的;如果食谱与食谱相关联,那么我会在我的用户模型中设置一个has_many:食谱,并在我的食谱模型中设置belongs_to:user。

由于用户是这里的“父”,我会选择在UsersController中创建一个食谱动作。将属于用户的配方放在用户控制器中,并将配方作为集合从用户访问,似乎更合乎逻辑。

或者,如果您尝试显示与用户关联的配方,我会将操作放在RecipesController中,并使用数据库中belongs_to关系设置的#user方法获取属于配方的用户

在任何一种情况下,您都希望保证在尝试呈现页面之前定义用户和/或任何配方。如果不存在试图访问的用户等,您可能希望显示501错误或类似错误。

如果你坚持应该总是有一个配方的用户,那么你应该将这种类型的验证添加到配方模型中,这样就不允许在没有用户的情况下添加配方:

validates :user, :presence => true

很抱歉,如果我稍微走了一会儿。

答案 1 :(得分:0)

get "/:username"

此处 - :username位于id

的位置
@user = User.find_by_username params[:username]

在这里,您试图通过参数找到它。

链接应如下http://localhost:3000/user_name/user_name?username=user_name

找到一些用户,显然不是你想要达到的目的。

get "/:id" => "recipes#index"

 @user = User.find(params[:id])