Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql Rails 3:为HABTM关系编写JOIN语句_Mysql_Ruby On Rails 3 - Fatal编程技术网

Mysql Rails 3:为HABTM关系编写JOIN语句

Mysql Rails 3:为HABTM关系编写JOIN语句,mysql,ruby-on-rails-3,Mysql,Ruby On Rails 3,我在:用户和:书籍之间有很多关系。他们加入了:owned_books模式。我的应用程序的一个功能是连接读过相同书籍的用户。目前,我在模型中的处理效率低下: users_hash = Hash.new users = User.all users.each do |user| if user != current_user users_hash[user.id] = 0 user.books.each do |book| if curre

我在:用户和:书籍之间有很多关系。他们加入了:owned_books模式。我的应用程序的一个功能是连接读过相同书籍的用户。目前,我在模型中的处理效率低下:

  users_hash = Hash.new
  users = User.all
  users.each do |user|
    if user != current_user
      users_hash[user.id] = 0
      user.books.each do |book|
        if current_user.books.include?(book)
          users_hash[user.id]+=1
        end
      end
    end
  end
  users_hash = users_hash.sort {|a,b| b[1]<=>a[1]}
  @users = Array.new
  users_hash[0..max].each do |id|
    user = User.find(id[0])
    @users << user
  end
end
我的意图是加入当前_用户已经阅读的书籍,然后统计所有其他用户,以查看他们已经阅读了多少这些书籍。然后,我将按此计数对结果进行排序,并限制为前100个结果


不幸的是,我的MySQL技能没有达到标准。特别是,我不确定如何为连接的模型编写条件。我也怀疑select语句是否会起作用,不过,一旦我有了solid joins语句,我可能就会明白这一点。

如果数据结构正确,通常可以在一次操作中获取所需的内容。在您的情况下,您可能需要稍微调整它以适应此结构:

class User < ActiveRecord::Base
  has_many :owned_books
  has_many :books,
    :through => :owned_books
end

class OwnedBook
  belongs_to :user
  belongs_to :book
end

class Book
  has_many :owned_books,
    :as => :owned_by
  has_many :users,
    :through => :owned_by
end

这有点冗长,因为这样可以避免重复用户。如果您只是使用常用书籍获取用户,那么每个用户可能会获得多个匹配项。这就是为什么要将DISTINCT条件添加到查询中。

注意,通常使用{}代替Hash.new,而[]比Array.new更可取。调用构造函数只是为了自定义散列或数组的操作方式。这似乎是可行的,但没有对用户进行排序。我的目的是根据用户与当前用户共享的图书数量来排序用户。我试图修改您的代码以这样做:User.select'users.*,COUNTowned_books WHERE book_id IN select book_id FROM owned_books WHERE User_id=?作为shared_books',current_user.id.ordershared_books DESC.limit100不幸的是,它引发了一个错误:1 select方法的参数数量错误2只接受一个参数,因此除非对查询执行sanitize_sql,否则可能无法工作。如果你创建了一个类方法,该类方法接受一个user_id参数并返回结果,那么你就可以轻松访问该方法。我已经对此进行了几个小时的修补,但即使在修复了错误数量的参数问题之后,我仍然会不断出现语法错误。我怀疑我不能像这样使用计数。在我看到的示例中,COUNT用于预先存在的列。我试着把东西调换一下,把计数直接放在.order里面,但是它不再识别共享的书籍了。关于如何解决这个问题有什么建议吗?这是一个不再识别共享书籍的代码。但感觉方向是正确的:User.select'users.*'。将'LEFT JOIN owned_books AS shared_books ON book_id加入到select book_id FROM owned_books,其中User_id=?',current_User.id.orderCOUNTshared_books DESC.limit100中
class User < ActiveRecord::Base
  has_many :owned_books
  has_many :books,
    :through => :owned_books
end

class OwnedBook
  belongs_to :user
  belongs_to :book
end

class Book
  has_many :owned_books,
    :as => :owned_by
  has_many :users,
    :through => :owned_by
end
User.where('id IN (SELECT DISTINCT user_id FROM owned_books WHERE book_id IN (SELECT book_id FROM owned_books WHERE user_id=?))', @user.id)).all