Я не понимаю ассоциацию модели «многие_к_одному ‹=› один_к_одному»

как сказать? Я не понимаю, что документация продолжения пытается сказать мне об ассоциациях в случае, если две модели связаны внешним ключом в одной модели A, являющейся первичным ключом в другой в случае may_to_one. Я всегда думал: если это много_к_одному в одном направлении, то должно быть одно_ко_многим в другом... но продолжение содержит запутанную главу, призванную прояснить тему, а также пример, который я не могу использовать.

В "Различия между many_to_one и one_to_one" говорится

Если вы хотите установить отношение 1-1 между двумя моделями, где внешний ключ > в одной таблице напрямую ссылается на связанную таблицу, вы должны использовать many_to_one в одной модели и one_to_one в другой модели. Как узнать, что использовать в какой модели? Самый простой способ запомнить, что модель, таблица которой имеет внешний ключ, использует many_to_one, а другая модель использует one_to_one.

И продолжает приводить этот странный пример:

# Database schema:
#  artists            albums
#   :id   <----\       :id
#   :name       \----- :artist_id 
#                      :name

class Artist
  one_to_one :album
end
class Album
  many_to_one :artist
end

В альбомах я могу найти несколько строк, указывающих на одного и того же исполнителя... почему бы исполнителю не указывать на все свои альбомы? Продолжение документа во многих случаях безумно трудно читать, но эта глава читается легко, но для меня не имеет смысла :(


person bachmarc    schedule 01.01.2018    source источник
comment
Поскольку вам нужно, чтобы отношение было указано только в одной таблице, а в случае отношения «многие к одному» имеет смысл иметь одно поле в каждой дочерней записи, указывающее на идентификатор родительской записи. Если вы ищете всех дочерних элементов родителя, вы запрашиваете все дочерние записи, имеющие поле parent_id, равное идентификатору родителя.   -  person moveson    schedule 01.01.2018
comment
Я согласен, что этот пример имеет очень мало смысла, поскольку он, кажется, подразумевает, что Artist может иметь только 1 Album (one_to_one), но многие Album могут принадлежать 1 Artist (many_to_one). Я думаю, что это просто означает показать разницу между ассоциациями, поскольку каждая из них более подробно описана выше, но они могли бы выбрать гораздо лучший пример.   -  person engineersmnky    schedule 02.01.2018
comment
Я сидел там перед не работающей моделью (в конце множественного числа s слишком много ... так как в дальнейшем не всегда понятно, имеется ли в виду модель или стол) ... Я открыл документ в 4 утра после долгого s ночь у экрана и обнаружил это «дополнительное коарирование»)... я до сих пор не могу представить себе ни одного сценария, где многие к одному логически удваиваются взамен один к одному. Вот почему я подумал, что пропустил большую концепцию, переходя от моделей sql к моделям сиквелов.   -  person bachmarc    schedule 02.01.2018
comment
one_to_one полезен, потому что он возвращает объект напрямую, в то время как во многих ассоциациях у вас есть массив. Это также быстрее, потому что заставляет сиквел выбирать первый результат вместо того, чтобы просматривать всю таблицу в поисках совпадений.   -  person three    schedule 14.01.2018


Ответы (1)


Та же проблема для меня.

require "logger"
require "sequel"

db = Sequel.connect "postgres://localhost/postgres", :logger => Logger.new(STDOUT)

db.drop_table :artists, :cascade => true if db.table_exists?(:artists)
db.create_table :artists do
  primary_key :id
  foreign_key :album_id, :albums
end

db.drop_table :albums, :cascade => true if db.table_exists?(:albums)
db.create_table :albums do
  primary_key :id
  foreign_key :artist_id, :artists
end

class Artist < Sequel::Model(db[:artists])
  one_to_one :album
end
class Album < Sequel::Model(db[:albums])
  one_to_one :artist
end

artist_1 = Artist.create
album_1  = Album.create

artist_1.update :album => album_1
album_1.reload
puts album_1.artist.nil?

artist_2 = Artist.create
album_2  = Album.create

album_2.update :artist => artist_2
artist_2.reload
puts artist_2.album.nil?

Мы можем исправить этот пример, заменив любой из one_to_one на many_to_one.

class Album
  many_to_one :artist
end

В этом случае artist.album_id использоваться не будет.

class Artist
  many_to_one :albums
end

В этом случае album.artist_id использоваться не будет.

Проблема в том, что имена методов one_to_one и many_to_one были выбраны базовой логикой sequel, и они не удобны для пользователя.

Вы можете создавать удобные псевдонимы для этих методов. Я предпочитаю просто использовать его с комментариями. Например:

db.create_table :artists do
  primary_key :id
  foreign_key :album_id, :albums
end    
db.create_table :albums do
  primary_key :id
end

class Artist < Sequel::Model(db[:artists])
  many_to_one :album # I have album_id foreign key
end
class Album < Sequel::Model(db[:albums])
  one_to_one :artist # I don't have artist_id foreign key
end
person puchu    schedule 19.03.2018