【问题标题】:Rails4 Complicated Nested has_many :through, need help to find the "rails way"Rails4复杂嵌套has_many:通过,需要帮助才能找到“rails方式”
【发布时间】:2013-12-05 16:31:47
【问题描述】:

我的目标是让用户能够提名来宾谈论一个主题,但复杂的是他们(或用户)可以提供许多“链接”来支持这种选择来提名来宾。

所以我的表格最简单的形式如下所示:

create_table "topics", force: true do |t|
    t.string   "name"
end
create_table "guests", force: true do |t|
    t.string   "name"
end
create_table "topic_guests", force: true do |t|
    t.integer  "topic_id"
    t.integer  "guest_id"
    t.integer  "user_id" #(who nominated this guest)
end
create_table "links", force: true do |t|
    t.integer  "user_id"
    t.integer  "topic_id"
    t.integer  "guest_id"
    t.string   "url"
end

我很难让链接与 has_many :through 一起使用,因为 :through 是另一个 has_many :through (whew) 的连接表。

主题和来宾的添加非常适合此配置:

class Topic < ActiveRecord::Base

  belongs_to :user

  has_many :topic_guests, :dependent => :destroy  
  has_many :guests, :through => :topic_guests

end

class Guest < ActiveRecord::Base
  has_many :topic_guests, :dependent => :destroy  
  has_many :topics, :through => :topic_guests
end

在为被提名的客人添加链接时,链接模型很简单:

class Link < ActiveRecord::Base
  belongs_to :guest
  belongs_to :topic
  belongs_to :user
end

但我似乎无法添加指向指定客人的链接。目标是做这样的事情(输入这个让我意识到为什么这是一项以“rails 方式”完成的艰巨任务)

@topic.guests.find(params[:guest_id]).links << current_user.links.build(link_params)

【问题讨论】:

    标签: activerecord ruby-on-rails-4 has-many-through


    【解决方案1】:

    我真的建议您坐下来认真思考模型之间的关系。有时它有助于在纸上绘制数据库以了解模型如何交互。有很多方法可以重组你拥有的数据。由于它实际上有些复杂,我将列出一些选项。

    使您的链接具有多态性

    这似乎是我第一个跳出来的,你应该让你的链接成为多态关系。这是一个 railscast(惊人的资源),http://railscasts.com/episodes/154-polymorphic-association-revised?view=asciicast

    对于您的模型,您可以通过几种方式进行设置。例如,客人和用户可以有许多多态链接,并且链接总是有一个主题 ID。这取决于您希望如何处理数据。迁移和模型看起来像这样

    class CreateLinks < ActiveRecord::Migration
      def change
        create_table :links do |t|
          t.references :authorable, index: true  # ex: user_id or guest_id
          t.string :authorable_type  # ex: user or guest
    
          t.references :topic, index: true
    
          t.string :url
    
          t.timestamps
        end
      end
    end
    

    模型看起来像这样,

    链接.rb

    class Link < ActiveRecord::Base
      belongs_to :authorable, :polymorphic => true
    
      belongs_to :topic
    end
    

    topic.rb

    class Topic < ActiveRecord::Base
      has_many :links
    end
    

    用户.rb

    class User < ActiveRecord::Base
      has_many :links, :as => :authorable
    end
    

    guest.rb

    class Guest < ActiveRecord::Base
      has_many :links, :as => :authorable
    end
    

    这只是一个例子,你可以很容易地反过来说链接属于用户,并使他们链接的任何内容都具有多态性。这进入了我的下一点,

    您可以将客人变成用户

    这不是一项要求,但它可以帮助您将所有来宾全部移除并让他们成为用户角色。就您在此处提供的内容而言,为了简单起见,我会将客人分开,并通过与客人和用户的关系使用 has_many,内表称为提名。

    has many through 的原因是您可能希望保存有关该关系的数据,例如它可能有一个名为success 的布尔字段,当他被成功提名时变为true。这是一个很好的链接,解释了很多,http://blog.hasmanythrough.com/2007/1/15/basic-rails-association-cardinality

    有很多通过给你很大的灵活性在这里

    现在,在这个特定示例中,您可能要使用的另一个原因有很多,您可以说提名属于_一个主题,而主题有_许多提名。我认为这是一种关联数据的好方法,但它确实取决于您比我更了解的数据之间更深层次的交互。

    是否仅在此应用中使用与提名和主题相关的链接?在这点上,客人只能被提名为一个主题吗?链接也可以用于多个主题吗?这些都是你需要问自己的好问题。我只能提出建议,但这假设您会比我更了解一些事情,因为您更了解该应用程序。

    我可以继续讨论应用程序对数据结构的影响程度,但这是我将使用的数据之间的最终联系:

    1. 用户通过提名有很多客人
    2. 来宾通过提名拥有许多用户
    3. 提名属于某个主题
    4. 主题有很多提名
    5. 提名有很多链接
    6. 链接属于提名
    7. 链接与创建它们的人是多态的(在我的示例中是可创建的)

    我认为这足以解决您的问题。祝你好运!

    【讨论】:

      猜你喜欢
      • 2012-11-10
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      相关资源
      最近更新 更多