如何在条件关联上编写查询

时间:2013-05-01 15:24:39

标签: ruby-on-rails

我想知道你是否可以帮我写一个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

1 个答案:

答案 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)