Рейки - використовувати стовпець типу без ІПСШ?


82

Я хочу використовувати стовпець, що викликається typeбез виклику успадкування єдиної таблиці (STI) - я просто хочу typeбути звичайним стовпцем, який містить String.

Як я можу це зробити, не маючи Rails, який очікує, що я отримаю успадкування однієї таблиці, і викину виняток The single-table inheritance mechanism failed to locate the subclass...This error is raised because the column 'type' is reserved for storing the class in case of inheritance.?

Будь-які ідеї щодо того, як це зробити?

Відповіді:


135

У Rails 3.1 set_inheritance_columnзастарілий, ви також можете просто використовувати його nilяк ім'я, наприклад:

class Pancakes < ActiveRecord::Base
    self.inheritance_column = nil
    #...
end

Власне, здається, ніби це змінилося в rails 3.2. За словами apidock : «Цей метод застарілий або переміщений на останню стабільну версію. Тут показана остання існуюча версія (v3.1.0). ' Дякую за підказку!
Batkins

Його було припинено в 3.1 і видалено в 3.2, я думаю
Валентин Немцев

2
@Batkins inheritance_columnЧитач переміщується (звідси повідомлення "застаріле або переміщене"). Використання inheritance_columnпрямого встановлення змінної екземпляра призначене і не припиняється.
lulalala

Працював у рейках 5.1
Джон Бахір

22

Ви можете замінити назву стовпця ІПСШ, використовуючи set_inheritance_column:

class Pancakes < ActiveRecord::Base
    set_inheritance_column 'something_you_will_not_use'
    #...
end

Тож виберіть ім’я стовпця, яке ви ні для чого не будете використовувати, і подайте його set_inheritance_column.


2
чи потрібно фактично створювати вказаний стовпець у моїй базі даних?
Квас

Дякую, це спрацювало. Фреймворк НІКОЛИ !!!!! НІКОЛИ !!!! диктувати, яке поле таблиці не може бути названо. Це вечеря погано для застарілих наборів даних.
Джон

5
@Jon: Rails насправді не турбується про застарілі дані або приємно поводитися з іншими, Rails занадто ставиться до цього. Ви можете змусити себе поводитись з певними зусиллями, але ви завжди закінчуєте трохи битися, якщо вам потрібно зробити щось, чого Rails не планував (що, на жаль, включає багато основних концепцій бази даних). ОТО, я професіонал-єретик, тому інші люди Rails, безумовно, будуть засмучені мною за те, що вони вказали на ідеологічні проблеми :)
mu занадто короткий

10
Я думаю, що ідея полягає в тому, що Rails / Ruby віддають перевагу конвенції перед конфігурацією, тому вони намагаються оптимізувати її для випадків використання, які, на їхню думку, є правильними.
Ібрагім

21

Я знаю, що це запитання досить давнє, і це трохи відхиляється від питання, яке ви задаєте, але те, що я роблю завжди, коли відчуваю бажання назвати тип стовпця або щось_типу, це пошук синоніму типу та використання замість нього:

Ось кілька альтернатив: вид, сорт, сорт, категорія, набір, жанр, види, замовлення тощо.


10

Рейки 4.x

Я зіткнувся з проблемою в Rails 4додатку, але в Rails 4set_inheritance_column метод не існує взагалі , так що ви не можете використовувати його.

Рішення , яке працювало для мене було , щоб відключити єдину таблицю спадкування шляхом перевизначення ActiveRecord«s inheritance_columnметод, як це:

class MyModel < ActiveRecord::Base

  private

  def self.inheritance_column
    nil
  end

end

Сподіваюся, це допоможе!


8
Simpler версія: class MyModel < ActiveRecord::Base self.inheritance_column = nil end. Довідка: apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods / ...
Benj

1
Працює у мене в рейках 4.2.2. Можливо, ви не перезапустили сервер або пружину після внесення змін?
Бендж,

1
А іншим користувачам може стати в нагоді простіша версія, яку я прокоментував. Що стосується проблеми перезавантаження, я не фахівець, але для мене було б сенсом мати властивість класу, яка не автоматично перезавантажується без вивантаження та перезавантаження визначення класу.
Benj,

2
Я не розумію вашої реакції, я просто намагаюся дати корисне доповнення до вашої відповіді. Чому ти почуваєшся ображеним? Я приходжу з миром
Бендж,

2
@Benj Схоже, вони видалили будь-які коментарі, на які ви посилаєтесь, тож тепер, схоже, ви сперечаєтесь із собою. ;)
Джошуа Пінтер

0

Якщо ви хочете зробити це для всіх моделей, ви можете вставити це в ініціалізатор.

ActiveSupport.on_load(:active_record) do
  class ::ActiveRecord::Base
    # disable STI to allow columns named "type"
    self.inheritance_column = :_type_disabled
  end
end

Або ще краще - в ApplicationRecord .
Олександр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.