我一直在借用我的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,错误不应该弹出。
感谢您的帮助!
答案 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])