我想知道你是否可以帮我写一个Rails的范围方法,我在完成时遇到了一些麻烦。我有一个用户可以提问的应用程序。问题根据类别和标签分类,即
Question.rb has_many :categories
Question.rb has_many :tags
当我显示问题时,我希望有一个显示类似问题的功能。为了做到这一点,我将根据以下条件显示其他问题
First, at least one category is the same
Second, at least one tag is the same
Third, the other question has at least one answer already.
在我的问题控制器的show动作中,找到问题之后,我会得到它的类别和标签
@question = Question.find(params[:id])
categories = @question.categories
tags= @question.tags
本地变量类别可能如下所示
[#<Category id: 3, name: "Wills & Estates", created_at: "2013-04-10 21:53:49", updated_at: "2013-04-10 21:53:49">, #<Category id: 4, name: "Business Law", created_at: "2013-04-10 21:53:49", updated_at: "2013-04-10 21:53:49">]
那么我所做的就是把这个名字从这个名字中删除
cats = Question.get_categories(categories)
在Question.rb模型上使用get_categories,如下所示
def self.get_categories(categories)
categories = categories.map(&:name)
end
我为标签做同样的事情
cats = Question.get_tags(tags)
Question.rb
def self.get_tags(tags)
tags = tags.map(&:name)
end
然后我将'cats'和'tags'(只是类别和标签的字符串)传递给Question.rb模型的范围
@similarquestions = Question.similar_questions(cats, tags)
这是我迷路的地方......
scope :similar_questions, lambda { |cats, tags|
joins(:categories).where(:categories { :name => cats})
joins(:tags).where(:tags { :name => tags })
}
局部变量'cats'和'tags'可能是单个字符串,或者它们可能是多个字符串,具体取决于特定问题的类别和标签的数量。如上所述,我找到类似问题的标准是让一个类别相同,一个标签相同(问题也至少有一个答案)。
你能不能指点我在这个范围内做些什么来完成我想要做的事情。我想知道我是否应该将数组作为局部变量传递并执行类似
的操作scope :similar_questions, lambda { |cats, tags|
cats.each do |cat|
joins(:categories).where(:categories { :name => cat})
end
tags.each do |tag|
joins(:tags).where(:tags { :name => tag })
end
}
但即便如此,我也无法找到实现我想要做的事情的方法。我担心的一个问题是我不想在范围内使用if / then子句的迷宫。我确信有一个更整洁的方式来做我想要的,但我无法弄清楚。我想在数组中传递的原因之一是检查某些内容是否在数组中等等。
如果您能提供帮助,请提前致谢。
更新
Question.rb has_many :answers
答案 0 :(得分:2)
scope :similar_questions, lambda {|question|
joins(:categories, :tags).includes(:answers).
where( categories: {name: question.categories.pluck(:name)},
tags: {name: question.tags.pluck(:name)} ).
where("questions.id != ? AND answers.id IS NOT NULL", question.id)
}
现在你可以做到:
@similar_questions = Question.similar_questions(self)