【问题标题】:Rails Association Terminology: Belongs_to and has_manyRails 协会术语:Belongs_to 和 has_many
【发布时间】:2016-05-11 16:39:08
【问题描述】:

我有两个关于 ActiveRecords 的问题:

1)

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

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

当我必须在 Rails 中创建关联时,我必须编写如下内容:

class User < ActiveRecord::Base
    belongs_to :photo
end

class Photo < ActiveRecord::Base
    has_many :Users
end

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

我做错了,还是我对 Rails 的术语思考过度了?

2)

新案例:

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

我还想添加一个可以包含照片的帖子实体,并且该照片可以被用户用作个人资料照片。

这是最终实现的样子:

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,似乎创建一对一关系的唯一方法是将两个外键放入 Photo 表中:一个用于 Post,一个用于 User。

但是,我希望在 User 表中为 Photo 设置一个外键,在 post 表中为 Photo 设置一个外键。在这种情况下,似乎需要这样实现:

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

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

【问题讨论】:

    标签: ruby-on-rails database activerecord associations


    【解决方案1】:

    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,但这对于您的要求来说效率很低。

    【讨论】:

    • 感谢您的回答,阅读此post 后,我决定最好将照片存储为文件,并仅使用照片实体将路径存储在数据库中。据我了解,照片类型的头像对象实际上将照片保存在数据库中。那正确吗?此外,在第一个解决方案中,用户似乎无法在无需复制的情况下共享同一张个人资料照片。 belongs_to 只允许一个用户外键,不是吗?
    • 我推测您使用诸如Paperclip 之类的东西来存储照片——将它们存储为文件,在数据库中引用它们。你想让我详细说明这种模式是如何工作的吗?
    • 不,没关系。我会读一读。感谢您对 Rich 的帮助!
    • 没问题。如果您有任何问题,请务必告诉我。 I met the Paperclip guys前段时间^_^
    • 太棒了!如果我最终遇到任何问题,我会告诉你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多