DataMapper - почему «имеет» и «принадлежит»? - PullRequest
4 голосов
/ 06 сентября 2011

Я только начинаю работать с DataMapper и пытаюсь понять, почему вам нужно указать has и belongs_to.

Например, посмотрите на пример на веб-сайте DataMapper. Разве это не избыточно? Если сообщение has n комментирует, то не комментирует автоматически belongs_to сообщение? Почему я должен указать это?

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

Ответы [ 3 ]

7 голосов
/ 06 сентября 2011

Вы указываете обе стороны отношения только тогда, когда хотите использовать методы, сгенерированные дополнительной спецификацией.Это совершенно необязательно: если вам никогда не нужно добираться до Post из Comment (например, @comment.post), вам не нужно указывать отношение belongs_to в Comment.

Одним из преимуществ является то, что ваши экземпляры немного чище, потому что в Comment дополнительные методы не генерируются автоматически.С другой стороны, если они вам нужны, эти дополнительные методы не будут вас беспокоить.

Смотрите также документацию об ассоциациях в ActiveRecord .

0 голосов
/ 27 сентября 2013

Я хотел бы добавить к этим хорошим ответам, что если вам требуется 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

Если вы используете has n, :comments в Post, но не включаете belongs_to :post в Comment, столбец post_id в таблице comments будет по-прежнему создаваться и индексироваться, но ограничение внешнего ключа не будет быть добавленным.

0 голосов
/ 06 сентября 2011

Это дает вам методы для легкого доступа к реляционному объекту.Такие как @post.comments @comment.post.Я понимаю, что вы имеете в виду, применение has_many может подразумевать принадлежность к нему.Несмотря на то, что с учетом накладных расходов разработчика на добавление own_to, это, вероятно, лучше, чем добавление дополнительных системных накладных расходов для динамического добавления методов к нужному классу.

Другое дело, если использовать отношение has_many через другое отношение has_many.Это может привести к нечетным отношениям own_to и, вероятно, к проблемам с SQL.

Например:

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

RolesUser - это таблица соединения, которая имеет значение для_ как для пользователя, так иобразцы для подражания.Подразумевает, что в этом случае «принадлежит», затем добавит к роли модели «принадлежность» для пользователя.Это также не имеет смысла, это также не будет работать из-за отсутствия там столбца базы данных.Конечно, это можно изменить, когда есть опция through, но, опять же, это значительно повысит сложность кода, когда он не нужен.Как сказал Даан в своем ответе, вам не нужно, чтобы оба работали, это необязательно.

...