Rails 协会术语:Belongs_to 和 has_many

Rails Association Terminology: Belongs_to and has_many

我有两个关于 ActiveRecords 的问题:

1)

假设我有一个包含多个用户的应用程序,每个用户都有一张个人资料照片。

我希望用户能够拥有与他们的朋友相同的个人资料照片:这会导致一对多关系,其中一张照片可以是许多用户的个人资料照片。

当我必须在 rails 中创建关联时,我必须这样写:

class User < ActiveRecord::Base
    belongs_to :photo
end

class Photo < ActiveRecord::Base
    has_many :Users
end

现在这对我来说有点奇怪,因为在这种情况下照片属于多个用户,而不是属于一张照片的多个用户。

我做错了还是我对 rails 的术语想得太多了?

2)

新案例:

假设用户可以拥有一张个人资料照片。在这种情况下,照片不能在用户之间共享,因此关系是一对一的。

我还想添加一个 post 可以包含照片的实体,用户可以将这张照片用作个人资料照片。

这是最终实现的样子:

class User < ActiveRecord::Base
    has_one :photo
end

class Photo < ActiveRecord::Base
    belongs_to :user
    belongs_to :post
end

class Post < ActiveRecord::Base
    has_one: Photo
end

通过查看 Rails Documentation,似乎创建一对一关系的唯一方法是将两个外键放入照片 table:一个用于 Post 和一个给用户。

但是我想在用户 table 中为照片设置一个外键,在 post table 中也为照片设置一个外键。在这种情况下,实施似乎需要这样:

class User < ActiveRecord::Base
    belongs_to :photo
end

class Photo < ActiveRecord::Base
    has_one :user
    has_one :post
end

class Post < ActiveRecord::Base
    belongs_to: Photo
end

从语义上讲,这对我来说也没有多大意义。再一次,我是做错了什么还是我想多了?

1)

#app/models/user.rb
class User < ActiveRecord::Base
    has_one :photo
    belongs_to :avatar, class_name: "Photo" #-> set this as the "avatar"
end

#app/models/photo.rb
class Photo < ActiveRecord::Base
    belongs_to :user
end

user可以创建照片;他可以定义他使用的avatar

@user  = User.find x
@photo = @user.avatar

虽然我仍然觉得它看起来有点奇怪,但我认为它会起作用。


2)

polymorphic

#app/models/post.rb
class Post < ActiveRecord::Base
   belongs_to :user
   has_one :photo, as: :imageable
end

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :posts
   has_one  :photo, as: :imageable

   belongs_to :avatar, class_name: "Photo"
end

#app/models/photo.rb
class Photo < ActiveRecord::Base
   belongs_to :imageable, polymorphic: true #-> belongs to either post or user
end

在这两种情况下,我都提倡使用 foreign_key 来为用户定义 avatar_id

这将意味着 belongs_to 关联(不理想),但意味着您可以 上传 任意数量的图片,引用其中一张作为头像.然后,您将能够根据个人资料中的要求调用 avatar 方法。

执行此操作的最佳方法是使用 join table / join model,但这对于您的要求来说效率很低。