【问题标题】:How do I get a Rails association to use a certain name to access a model of a different name?如何让 Rails 关联使用某个名称来访问不同名称的模型?
【发布时间】:2016-05-01 02:23:44
【问题描述】:

假设我有一个用户模型和一个电影模型以及存储它们的表。假设我想通过添加名为 watchlist_movies 的第三个表来添加监视列表功能,该表只是将 user_id 映射到 movie_id。

我现在想添加一个 watchlist_movie 模型。我希望能够使用 user.watchlist_movies 查询 ActiveRecord 并获取电影对象的集合。到目前为止,我已经尝试过(在 user.rb 中)

has_many :watchlist_movies 

和

has_many :movies, through: watchlist_movies

第一个结果 user.watchlist_movies 返回一个记录,第二个结果将返回 user.movi​​es 的电影记录集合。基本上我想要的是 user.watchlist_movies 返回电影记录的集合,所以我希望第一个关系中定义的访问返回第二个关系的内容。我该怎么做?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord rails-models object-relationships


    【解决方案1】:

    您在这里正确地定义了关系,但您可能会遇到您的期望与 Rails 的工作方式不一致的情况。如果您的结构是 Movie 通过 WatchlistMovie 与 User 相关联的结构,这是一个简单的连接模型,那么您就在正确的轨道上。

    请记住,您可以随意称呼您的关系:

    has_many :watchlist_movie_associations,
      class_name: 'WatchlistMovie'
    
    has_many :watchlist_movies,
      class_name: 'Movie',
      through: :watchlist_movie_associations
    

    我建议不要这样做,因为它违背了 ActiveRecord 喜欢命名事物的方式。如果它现在只是困扰你,那是可以理解的,但如果你接受这种风格而不是反对它,你将拥有一个更加一致和易于理解的应用程序。

    【讨论】:

    • 所以我不清楚你认为建立这种关系的最佳方式是什么。你是说 has_many :movies, through: watchlist_movies 是理想的吗?
    • 您在原始问题中的做法是教科书式的做法,除非您有充分的理由,否则我会避免更改名称。个人偏好,当它与 Rails 约定相矛盾时,通常应该被忽略。一致性导致未来的意外更少。你现在可能会觉得奇怪,但大多数 Rails 开发人员发现你的代码完全符合预期,这也是他们的做法。打电话给user.watchlist_movies 并找回一个电影模型对于不熟悉你的命名约定的人来说真的很困惑。
    • 很公平。如果我走那条路,我什至应该有一个 watchlist_movies 模型吗?我不能只使用没有模型的连接表并使用 has_and_belongs_to_many 关联吗?另外,我不想使用 user.movi​​es 的一个原因是因为将来他们可能有其他列表。他们也会通过其他协会获得电影。
    • 如果您与同一个模型有两个或多个关系,您想要将其命名为不同的情况。例如,如果用户被列在电影的演职员表中,并且也可以收藏它们。然后你会有两个has_many :through 关系,这意味着你需要为它们选择名字。我会选择 movies_on_watchlist 和 movies_with_credits 或类似的东西。
    • 所以我选择了最后一种方法(user_movies)。唯一的问题是,当我尝试在 ActiveRecord 查询上调用 .include(:movie) 时,它给了我一个 TypeError 并说它不需要符号而是模块。你知道是什么原因造成的吗?
    猜你喜欢
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    相关资源
    最近更新 更多