class Recipe < ActiveRecord::Base
def self.tagged_with(name)
recipes = Tag.find_by(name: name).recipes
end
end
在控制器中
def tag
@recipes = Recipe.tagged_with(params[:tag])
render 'index'
end
路线
get 'tag/:tag', to "recipes#tag"
如何保护此方法免受破坏?如果我搜索一个尚未创建的标记,我会得到一个noMethodError'recipes'代表nil:NilClass。我试过把
return false if recipes.nil?
以及
redirect_to(recipes_path) if recipes.nil?
在方法的最后但没有任何工作。
答案 0 :(得分:1)
它会抛出该错误,因为当Tag#find_by
返回的值为nil
时,它无法在其上调用方法recipes
。换句话说,nil
没有recipes
方法。
尝试先检查标签是否存在,例如:
class Recipe < ActiveRecord::Base
def self.tagged_with(name)
tag = Tag.find_by(name: name)
recipes = tag.recipes unless tag.nil?
end
end
我不知道您组织数据的方式,但更好的方法可能就是这样:
class Recipe < ActiveRecord::Base
def self.tagged_with(name)
Recipe.find_by(tag: name)
end
end
答案 1 :(得分:0)
def self.tagged_with(name)
tag = Tag.find_by(name: name)
if !tag.nil?
recipes = tag.recipes
else
return false
end
end
在控制器中:
def tag
@recipes = Recipe.tagged_with(params[:tag])
if @recipes != false
render 'index'
else
redirect_to root_path
end
end
答案 2 :(得分:0)
您看到NoMethodError,因为您在NilClass上调用方法recipies
。find_by
方法返回nil
如果找不到任何内容(顺便说一句,find
会引发异常,{ {1}}返回空关系)
所以,首先你要做的是使用where
:
`
try
class Recipe < ActiveRecord::Base
def self.tagged_with(name)
recipes = Tag.find_by(name: name).try(:recipes)
end
end
将默默返回try
但是,您可以使用nil
更好的方法(假设您有scope
关系):
`
tags
或许,您可能希望在结果关系上调用class Recipe < ActiveRecord::Base
has_many :tags
scope :tagged_with, ->(name) { joins(:tags).where(tags: { name: name }) }
end
或者不在范围等中使用uniq
。