【问题标题】:Protecting a method from returning nil on a relation防止方法在关系上返回 nil
【发布时间】:2015-03-07 19:59:40
【问题描述】:
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' for nil:NilClass。我试过放

return false if recipes.nil?

还有

redirect_to(recipes_path) if recipes.nil?

在方法结束时,但没有任何效果。

【问题讨论】:

  • if recipes &amp;&amp; recipes.nil?

标签: ruby-on-rails ruby tagging


【解决方案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

【讨论】:

  • 我没有标签列,我已经尝试了你的第一个建议,但它不起作用
  • @Kohl,什么不完全有效?你能告诉我错误信息吗?
  • 别担心,我想通了。感谢您的帮助
【解决方案2】:
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

【讨论】:

    【解决方案3】:

    您看到 NoMethodError 是因为您在 NilClass 上调用方法 recipiesfind_by 方法返回 nil 如果没有找到(顺便说一下,find 会引发异常,而 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 或不在范围内使用 joins 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多