你如何在铁轨中模仿“喜欢”?

时间:2012-08-14 03:43:03

标签: ruby-on-rails ruby model

我有3个模型:用户,对象,喜欢

目前,我有模型:用户有很多对象。我如何进行建模:

1)用户可以喜欢很多对象

2)一个对象可以有很多喜欢(来自不同的用户)

所以我希望能够做到这样的事情:

User.likes =用户喜欢的对象列表

Objects.liked_by =按对象喜欢的用户列表

下面的模型肯定是错误的......

class User < ActiveRecord::Base
  has_many :objects
  has_many :objects, :through => :likes
end

class Likes < ActiveRecord::Base
  belongs_to :user
  belongs_to :object
end

class Objects < ActiveRecord::Base
  belongs_to :users
  has_many :users, :through => :likes    
end

4 个答案:

答案 0 :(得分:17)

为了进一步阐述我对Brandon Tilley的回答,我建议如下:

class User < ActiveRecord::Base
  # your original association
  has_many :things

  # the like associations
  has_many :likes
  has_many :liked_things, :through => :likes, :source => :thing
end

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :thing
end

class Thing < ActiveRecord::Base
  # your original association
  belongs_to :user

  # the like associations
  has_many :likes
  has_many :liking_users, :through => :likes, :source => :user
end

答案 1 :(得分:4)

你很亲密;要使用:through关系,首先必须建立您正在经历的关系:

class User < ActiveRecord::Base
  has_many :likes
  has_many :objects, :through => :likes
end

class Likes < ActiveRecord::Base
  belongs_to :user
  belongs_to :object
end

class Objects < ActiveRecord::Base
  has_many :likes
  has_many :users, :through => :likes    
end

请注意,Objects应为has_many :likes,以便外键位于正确的位置。 (另外,您应该使用单数形式LikeObject作为模型。)

答案 2 :(得分:1)

这是实现此目的的简单方法。基本上,只要使用:class_name选项指定正确的类名,就可以根据需要创建任意数量的关系。但是,这并不总是一个好主意,因此请确保在任何给定请求中只使用一个,以避免其他查询。

class User < ActiveRecord::Base
  has_many :likes, :include => :obj
  has_many :objs
  has_many :liked, :through => :likes, :class_name => 'Obj'
end

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :obj
end

class Obj < ActiveRecord::Base
  belongs_to :user
  has_many :likes, :include => :user

  has_many :users, :through => :likes

  # having both belongs to and has many for users may be confusing 
  # so it's better to use a different name

  has_many :liked_by, :through => :likes, :class_name => 'User'   
end


u = User.find(1)
u.objs # all objects created by u
u.liked # all objects liked by u
u.likes # all likes    
u.likes.collect(&:obj) # all objects liked by u


o = Obj.find(1)
o.user # creator
o.users # users who liked o
o.liked_by # users who liked o. same as o.users
o.likes # all likes for o
o.likes.collect(&:user)

答案 3 :(得分:0)

模型&amp;根据轨道建模的命名约定的关联

class User < ActiveRecord::Base
  has_many :likes
  has_many :objects, :through => :likes
end

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :object
end

class Object < ActiveRecord::Base
  belongs_to :user

  has_many :likes
  has_many :users, :through => :likes    
end

此外,您可以使用已经内置的宝石(如acts-as-taggable-on)来获得相同的功能而无需代码:)