我坚持使用这个应用程序) 我有3个型号 - 用户,照片和喜欢 用户将登录,查看照片并将其标记为“喜欢”或“不喜欢”。 这是我的数据库架构,为了酿造而跳过了无关紧要的字段:
create_table "likes", :force => true do |t|
t.integer "oid" # oid is photos.id
t.integer "user_id" # user who liked this photo
t.boolean "mark", :default => true
end
create_table "photos", :force => true do |t|
t.string "photo" #filename of the photo
end
create_table "users", :force => true do |t|
t.string "firstname",
t.string "lastname",
t.string "email",
end
这是模特:
class Photo < ActiveRecord::Base
has_many :likes, :foreign_key => 'oid'
end
class Like < ActiveRecord::Base
belongs_to :photo
end
class User < ActiveRecord::Base
has_many :likes, :through => :photos
end
一张照片每位用户只有一个标记。即用户不能“喜欢”两次或两次以上的照片。
我希望用户能够在重新登录后看到他们给出了估计的照片。
目前,我使用此声明选择照片: @photos = Photo.limit(30).offset(0) 然后在模板中: &lt;%= photo.likes.where(“user_id =#{current_user.id}”)%&gt; 在此之后,我有30多个SQL查询,换句话说,我有N + 1个问题。
避免此问题的一个选择是在选择照片时加入喜欢。
@photos = Photo.includes(:likes ).limit(30).offset(0)
但是这将包括来自所有用户的所有喜欢照片,并对应用程序的性能产生负面影响。另外,我必须为当前用户提取记录。
第二个选项是创建动态关系
class User < ActiveRecord::Base
has_many :likes, :through => :photos, :conditions => "user_id = current_user.id"
end
对于这个选项,我必须将current_user.id从控制器传递给模型,这对我来说看起来不正确。
请帮助解决此问题
答案 0 :(得分:3)
首先,这是一个设计问题。想一想:“喜欢”是用户和照片之间的某种联系。只要大声说:“许多用户可能会喜欢这张照片;用户可能会喜欢很多照片”。
您的Like
模型应该介于Photo
和User
模型之间,这不清楚吗?
.----------.1 0..*.----------.0..* 1.----------.
| users |<-------| likes |-------->| photos |
'----------' '----------' '----------'
class User < ActiveRecord::Base
has_many :likes
has_many :liked_photos, through: :likes, class: 'Photo'
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :photo
# this will ensure that your users can only like a photo once.
# you can also add a unique index to the two columns using
# add_index in a migration for more safety and performance.
validates_uniqueness_of [:user, :photo]
end
class Photo < ActiveRecord::Base
has_many :likes
has_many :liking_users, through: :likes, class: 'User'
end
现在,您必须这样做才能有效地检索相关图片:
@user = User.includes( likes: :photos ).find( current_user.id )
@photos = @user.liked_photos