【问题标题】:Rails Has Many AssociationRails 有很多关联
【发布时间】:2012-07-30 13:55:15
【问题描述】:

我几乎没有什么问题困扰着我,需要回答。一切都与以下教程有关Two Many-to-Many

问题 1

使用 has_many 的连接表是否需要有 id?还是删除ID的最佳做法?并添加一个索引并使用另外两个主键并将其设置为唯一并一起?

问题 2

在建表的迁移中怎么做?

问题 3

在完成这些关系模型并更新数据之后。我想在每次更新时创建一组新数据(以保留数据)。控制器在更新、新建、创建模型中的外观如何?

问题 4

在中间表中,我想设置属性,比如有一个可见的真或假,我怎样才能不仅设置第三个表,还设置第二个表参数

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 associations


    【解决方案1】:

    首先...提醒一句:railscast 已经很老了。在那一集中,可能有一些语法上的东西已经被新版本的 rails 过时了。

    问题 1

    如果您使用的是 has_many through 方法,那么您必须在连接模型中有一个 id 列,因为您使用的是成熟的模型。正如 Ryan 在剧集中提到的,如果您需要跟踪其他信息,您将选择此方法。如果您使用 has_and_belongs_to_many 方法,您的表中将没有 id 列。
    如果您想在多对多关联中实现不允许重复的检查(即允许将项目 a 与项目 b 配对,并再次允许项目 a 到项目 b 的另一条记录),您可以使用简单的使用范围验证行:

    validates_uniqueness_of :model_a_id, :scope => [:model_b_id]
    


    问题 2

    您可以使用此代码在迁移中添加索引

    add_index :table_name, [ :join_a_id, :join_b_id ], :unique => true, :name => 'by_a_and_b'
    

    这将被插入到您的 create_table 语句下方的更改块中(但不在该 create_table 块中)。查看这个问题了解更多详情:In a join table, what's the best workaround for Rails' absence of a composite key?

    问题 3

    我并不完全清楚您要完成什么,但如果您想在每次将新记录插入连接模型时采取一些措施,我会使用 after_create 活动记录挂钩。看起来像这样。

    class YourJoinModel < ActiveRecord::Base
    
      after_create :do_something
    
      def do_something
        puts "hello world"
      end
    end
    

    每次创建新记录时都会调用该函数 do_something。

    问题 4

    使用 has_many through 方法可以让您访问您在该模型中定义的关系两侧的附加属性。例如,如果您有这样的设置:

    class Factory < ActiveRecord::Base
      has_many :widgets, :through => :showcases
    end
    
    class Widget < ActiveRecord::Base
      has_many :factories, :through => :showcases
    end
    
    class Showcases < ActiveRecord::Base
      belongs_to :factory
      belongs_to :widget
    
      attr_accessiable :factory_id, :widget_id, :visible
    end
    

    你可以这样说

    widget = Widget.first
    shown = widget.showcases
    shown.first.visible
    

    或

    shown = widget.showcases.where( :visible=> true )
    

    您也可以联系其他协会:

    shown.first.factory
    

    【讨论】:

    • 谢谢这让我明白我假设我会在创建时在控制器中执行widget = widget ...代码。这是我唯一的最后一个问题,如果我在一个页面中有多个模型,是否可以通过操作设置部分模型?
    【解决方案2】:

    在关联中包含id 列的原因是它为您提供了一种删除该特定关联的方法,而无需担心它所具有的关系。如果没有该标识符,除了指定所有外键之外,很难定义关联。

    对于您的密钥只有两个组件的微不足道的情况,这并不是一个很大的差异化因素,但通常您将拥有三个或更多作为您的唯一约束的一部分,并且事情变得棘手。

    拥有id 也使这种关系成为一流的模型。当您操作具有关联元数据的元素时,这可能很有用。这也意味着您可以在以后毫不费力地添加元数据。这就是您所说的“问题4”的意思。将这些属性添加到连接模型中。

    通常,连接模型的创建方式与其他模型相同。主键是id,您可以创建一系列辅助键:

    create_table :example_things |t|
      t.integer :example_id
      t.integer :thing_id
    end
    
    add_index :example_joins, [ :example_id, :thing_id ], :unique => true
    add_index :example_joins, :thing_id
    

    主要的unique 索引用于防止重复并允许查找密钥对。次要用作提取给定thing_id 的所有example_id 的一种方式。

    在连接模型上操作元数据的常用方法是直接获取它们:

    @example_things = @example.example_things.includes(:thing)
    

    这会加载与示例关联的 ExampleThing 和 Thing 模型。

    【讨论】:

    • 谢谢,这可以帮助我清除问题。我的问题 4 的意思是如何操作数据,我有 3 个表客户、音乐和一个音乐管理器(属于 customerid、musicid),我想向音乐添加内容,但与有价值的音乐管理器保持联系可见真假
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多