【问题标题】:DataMapper - why "has" and "belongs_to"?DataMapper - 为什么是“has”和“belongs_to”?
【发布时间】:2011-11-11 11:05:10
【问题描述】:

我刚刚开始使用 DataMapper,我想弄清楚为什么需要指定 hasbelongs_to

例如,查看 DataMapper 网站上的示例。这不是多余的吗?如果 Post has n cmets,那么 belongs_to post 不会自动评论吗?为什么我必须指定这个?

class Post
  include DataMapper::Resource

  property :id, Serial

  has n, :comments
end

class Comment
  include DataMapper::Resource

  property :id,     Serial
  property :rating, Integer

  belongs_to :post  # defaults to :required => true

  def self.popular
    all(:rating.gt => 3)
  end
end

【问题讨论】:

    标签: ruby sinatra ruby-datamapper


    【解决方案1】:

    仅当您想使用由额外规范生成的方法时,才指定关系的双方。这完全是可选的:如果您永远不需要从 Comment(例如 @comment.post)访问 Post,则不必在 Comment 中指定 belongs_to 关系。

    一个优点是您的实例更干净一些,因为在Comment 中不会自动生成其他方法。另一方面,如果您需要它们,那些额外的方法不会打扰您。

    另请参阅documentation about associations in ActiveRecord

    【讨论】:

      【解决方案2】:

      这为您提供了轻松访问关系对象的方法。比如@post.comments@comment.post。我明白你的意思,应用has_many 可能意味着belongs_to。尽管考虑到添加belongs_to 的开发人员开销,但可能比添加更多系统开销以动态地将方法添加到正确的类要好。

      另一件事是通过另一个 has_many 关系使用 has_many 关系。这会导致奇怪的belong_to 关系,并且可能会导致SQL 出现问题。

      例如:

      class User < ActiveRecord::Base
        has_many :roles, :through => :roles_users
        has_many :roles_users
      end
      

      RolesUser 是一个连接表,其中包含用户和角色模型的 belongs_to。在这种情况下,暗示属于会向用户添加一个属于角色模型的 belongs_to。这也没有任何意义,由于缺少数据库列,它也不起作用。当然,当存在 through 选项时,可以对其进行调整,但是当不需要时,这又会大大提高代码的复杂性。正如 Daan 在他的回答中所说,你不需要两者都可以工作,它是可选的。

      【讨论】:

        【解决方案3】:

        我想补充一下,如果您需要dm-constraints(直接或通过data_mapper)并使用auto_migrate!,那么belongs_to 将自动在数据库级别添加外键约束,而仅has 不会这样做。

        例如:

        require 'data_mapper'
        
        class Post
          include DataMapper::Resource
          property :id, Serial
        end
        
        class Comment
          include DataMapper::Resource
          property :id, Serial
        
          belongs_to :post
        end
        

        产生这个(通过 MySQL 适配器):

         ~ (0.140343) CREATE TABLE comments (id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        post_id INT(10) UNSIGNED NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB
        CHARACTER SET utf8 COLLATE utf8_general_ci
        
         ~ (0.234774) CREATE INDEX index_comments_post ON comments (post_id)
        
         ~ (0.433988) ALTER TABLE comments ADD CONSTRAINT comments_post_fk
        FOREIGN KEY (post_id) REFERENCES posts (id) ON DELETE NO ACTION ON UPDATE NO ACTION
        

        如果您在Post 中使用has n, :comments,但选择不在Comment 中包含belongs_to :post,则comments 表中的post_id 列仍将被创建和索引,但不会有外键约束被添加。

        【讨论】:

          猜你喜欢
          • 2012-01-07
          • 2012-10-30
          • 1970-01-01
          • 1970-01-01
          • 2011-04-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多