11

我有 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

4 回答 4

18

为了进一步详细说明我对 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
于 2012-08-14T07:21:20.270 回答
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

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

于 2012-08-14T03:46:04.933 回答
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)
于 2012-08-14T06:34:16.943 回答
0

根据导轨建模的命名约定的模型和关联

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

此外,您可以使用已经内置的 gems,比如acts-as-taggable-on,在没有代码的情况下拥有相同的功能:)

于 2012-08-14T07:24:46.107 回答