2016-01-14 2 views
1

У меня есть текущая структура модельнуюКак иметь HAS_ONE с псевдонимом в Rails 4+

publisher 
--------- 
has_many :digest_templates 
has_one :active_template 

digest_templates 
--------- 
belongs_to :publisher, optional: true 

Структура базы данных:

publishers 
--------- 
t.string :name 
t.string :permalink 
t.string :api_key 
t.string :domain 
t.reference :digest_template, index: true, foreign_key: true 

digest_templates 
--------- 
t.text :html 
t.text :text 
t.references :publisher, index: true, foreign_key: true 
t.boolean :global, default: false # this is for internally developed templates 

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

Publisher.templates и Publisher.active_template

Основная проблема заключается в том, что у меня есть глобальные шаблоны и созданные пользователем шаблоны в той же таблице. Можно ли работать с этой архитектурой? Или есть лучший способ сделать что-то?

+0

активный шаблон будет также шаблон дайджеста в то же время? Если это так, вы дважды сохраняете одни и те же данные в базе данных. –

+0

@ArslanAli Активный_template - это только ссылка на идентификатор digest_template, который активен. –

+0

Кажется, что это сработает. В чем проблема, с которой вы сталкиваетесь? Что должно вернуть 'publisher.templates'? Должен ли он просто вернуть все ассоциации 'digest_templates' из отношения' has_many'? –

ответ

0

Для простейшего случая, я бы сказал, чтобы добавить столбец active типа boolean в digest_templates, и добавить проверку, как:

validate_uniqueness_of :active, if: :active_template? 

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

Теперь вам нужно определить только одну взаимосвязь, такую ​​как has_many :templates, и вы можете определить методы экземпляра для получения активного шаблона.

+0

Это не работает, если у издателя есть шаблон по умолчанию как глобальный. У них нет этого шаблона, поэтому нет возможности рассказать. –

+0

Итак, шаблон принадлежит пользователю двумя способами: 1) Пользователь может быть владельцем этого шаблона; 2) Пользователь может иметь этот шаблон в качестве шаблона по умолчанию. Правильно? –

+0

есть. Однако есть еще одна вещь: когда пользователь сначала создается, ему присваивается шаблон по умолчанию, который называется «глобальным» (другими словами, он доступен для всех пользователей) –

1

Несколько вопросов:

  1. Вам не нужно t.references :digest_template в вашем publishers столе (если это has_many, все внешние ключи будут находиться в соответствующей таблице, которая you've got already)

  2. Вы» ve не определено, является ли шаблон «активным» или нет в db


Самая большая проблема, которую я вижу, заключается в том, что невозможно определить, является ли шаблон «активным». Я хотел бы добавить столбец Его к вашей publishers таблице под названием active:

# db/migrate/add_active_to_templates______.rb 
class DigestTemplate < ActiveRecord::Migration 
    change_table :templates do |t| 
     t.boolean :active, default: :false 
    end 
end 

Узора у вас есть то, что в templatebelongs_topublisher, что дает вам возможности для работы с. Затем возникает вопрос, как вы определяете, какой из ваших шаблонов «активен».

Решение, которое я хотел бы использовать следующим образом:

#app/models/digest_template.rb 
class DigestTemplate < ActiveRecord::Base 
    belongs_to :publisher 
    validates :active, uniqueness: { scope: :user_id } 
    scope :active, -> { where active: true } 
end 

Это позволит вам позвонить:

#app/models/publisher.rb 
class Publisher < ActiveRecord::Base 
    has_many :digest_templates 

    def active_template 
     digest_templates.find_by active: true 
    end 
end 

-

Ваш вопрос был немного плохого в том смысле, что вам не смог бы позвонить Publisher.active_template, так как это класс метод.

Вы должны были бы сделать следующее:

@publisher = Publisher.find params[:id] 
@publisher.digest_templates #-> returns all (including active) 
@publisher.active_template #-> returns only active 
+0

Как и в случае с Arslan, это в основном правомерно, за исключением факта что существуют глобально доступные шаблоны (где для параметра 'global' установлено значение true). Это шаблоны по умолчанию, доступные для ВСЕХ пользователей. Поэтому просто установка 'active' в true не будет работать в этом случае. –