0

我想知道您是否可以帮助我为 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.

在问题控制器的显示操作中,找到问题后,我会获取它的类别和标签

@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)

问题.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
4

1 回答 1

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)
于 2013-05-01T15:40:16.300 回答