Несколько ассоциаций has_one / own_to - PullRequest
0 голосов
/ 05 июня 2018

Рельсы 5 - у меня есть модели группы и места встречи.У меня есть общая модель, которую я хочу использовать для информации, общей для группы и модели.Я не могу понять отношения правильно.

Band.rb

class Band < ApplicationRecord
    has_one :common
    accepts_nested_attributes_for :common, allow_destroy: true
end

схема группы

  create_table "bands", force: :cascade do |t|
    t.integer "user_id"
    t.integer "plan_id"
    t.string "band_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "common_id"
    t.index ["common_id"], name: "index_bands_on_common_id"
  end

common.rb

class Common < ApplicationRecord
  belongs_to :band
end

общая схема.Примечание - нет ключа для связи с группой.Я почти уверен, что ошибся.

  create_table "commons", force: :cascade do |t|
    t.integer "user_id"
    t.integer "plan_id"
    t.string "name"
    t.string "address1"
    t.string "address2"
    t.string "city"
    t.string "state"
    t.string "zip"
    t.string "website"
    t.string "phone1"
    t.string "phone1_note"
    t.string "phone2"
    t.string "phone2_note"
    t.string "short_description"
    t.text "long_description"
    t.integer "main_photo_id"
    t.boolean "payment_current"
    t.decimal "lat"
    t.decimal "lon"
    t.text "admin_notes"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Я думал, что common_id будет использоваться в модели групп, но, видимо, я ошибаюсь.

У меня нет общих ключей в общей модели.

Как настроить мои модели таким образом, чтобы я мог иметь:

Полоса - Общая

Место проведения - Общая

Если я поставлю иностраннуюключ band_id в общей модели, что происходит, когда я пытаюсь сделать ту же связь с объектами.Добавить Venue_id к общей модели?

Ответы [ 3 ]

0 голосов
/ 05 июня 2018

Все, что я могу видеть, это то, что вам нужно отношение многих ко многим, так как группа может играть на любом количестве мест, а место может принимать любое количество групп, что-то вроде

class Band < ApplicationRecord
    has_many :common - make sure you handle the plural
    has_many :venues, through: :common
end

class Venue < ApplicationRecord
    has_many :common - make sure you handle the plural
    has_many :bands, through: :common
end

class Common < ApplicationRecord
    belongs_to :band
    belongs_to :venue
end

и да, вам нужноиметь band_id и venue_id в общей модели, и я бы сказал, что вы можете даже назвать свою общую модель как Event как более похожую на сущность реального мира.

0 голосов
/ 05 июня 2018

Возможно, вам следует использовать полиморфную ассоциацию.

Итак, Common (плохое имя, IMO) может выглядеть следующим образом:

# == Schema Information
#
# Table name: commons
#
#  id                 :integer          not null, primary key
#  commonable_id      :integer 
#  commonable_type    :string
#  ... other stuff ...
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#
class Common < ApplicationRecord
  belongs_to :commonable, polymorphic: true 
  ... other stuff ...
end

Обратите внимание, что у вас будет commonable_type и commonable_id, что позволяетполиморфизм.

Тогда Band может выглядеть так:

class Band < ApplicationRecord
  has_one :common, as: :commonable
  ... other stuff ...
end

Аналогично, Venue может выглядеть так:

class Venue < ApplicationRecord
  has_one :common, as: :commonable
  ... other stuff ...
end

Что позволит вам сделать:

@venue.common
@band.common

Кстати, Common выглядит как смесь по крайней мере пары классов-кандидатов, а именно PhysicalAddress и PhoneNumber.

Итак, у вас может быть что-то вроде:

# == Schema Information
#
# Table name: phone_numbers
#
#  id                 :integer          not null, primary key
#  phoneable_id       :integer 
#  phoneable_type     :string
#  number             :string
#  note               :string
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#
class PhoneNumber < ApplicationRecord
  belongs_to :phoneable, polymorphic: true
end

И

# == Schema Information
#
# Table name: physical_addresses
#
#  id                           :integer          not null, primary key
#  physical_addressable_id      :integer 
#  physical_addressable_type    :string
#  address1                     :string
#  address2                     :string
#  city                         :string
#  state                        :string
#  zip                          :string
#  created_at                   :datetime         not null
#  updated_at                   :datetime         not null
#
class PhysicalAddress < ApplicationRecord
  belongs_to :physical_addressable, polymorphic: true
end

А затем выполните:

class Band < ApplicationRecord
  has_one :common, as: :commonable
  has_one :physical_address, as: :physical_addressable
  has_one :phone1, as: :phoneable, class_name: 'PhoneNumber'
  has_one :phone2, as: :phoneable, class_name: 'PhoneNumber'
end

Вам понадобитсячто class_name, поскольку rails не сможет вывести имя класса (PhoneNumber) из имени ассоциации (phone1 и phone2).

0 голосов
/ 05 июня 2018

Да, вам нужно добавить venue_id и band_id в общую таблицу.У общей сущности будет несколько множественных принадлежностей (то есть, принадлежащих: принадлежащих ей, то есть принадлежащих ей, то есть 1001 *

. Каскадирование будет выполняться со стороны Бэнда и места проведения, поскольку в общей сущности существует принадлежность, принадлежащая принадлежащему этому месту, и это отношение many_to_one / one_to_one.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...