Mysql Rails 3:为HABTM关系编写JOIN语句
我在:用户和:书籍之间有很多关系。他们加入了:owned_books模式。我的应用程序的一个功能是连接读过相同书籍的用户。目前,我在模型中的处理效率低下: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
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