Направляет множественные отношения has_many через одну модель - PullRequest
1 голос
/ 25 августа 2011

Мне интересно, как я могу справиться со следующей ситуацией:

Page has_many Assets

Stylesheet has_many Assets

Javascript has_manyAssets

Теперь я хочу иметь возможность выполнять следующие запросы:

Page.first.assets # показывает все ресурсы (таблицы стилей и JavaScript) для этой страницы

Page.first.assets.javascripts # показывает все ресурсы javascript для этой страницы (то же самое для таблиц стилей)

Javascript.first.pages # показывает все страницы, которые включают этот javascript (то же самое для таблиц стилей)

У меня сейчас есть такая настройка:

Assets:
  stylesheet_id
  javascript_id
  page_id

  belongs_to :stylesheet
  belongs_to :javascript
  belongs_to :page

  scope :stylesheets, where{ stylesheet_id != nil } ###
  scope :javascripts, where{ javascript_id != nil } # uses "squeel" gem

Pages:
  has_many :assets
  has_many :stylesheets, through: :assets
  has_many :javascripts, through: :assets

Stylesheets/Javascripts:
  content (text field)

  has_many :assets
  has_many :pages, through: :assets

Проблема в том, что это не работает

Однако, мне кажется, что это не правильный путь, потому что у меня три *_id поля в модели Assets.javascript_id, stylesheet_id и page_id.В каждой строке javascript_id или stylesheet_id будут пустыми в этой ситуации, что для меня похоже на запах кода.

Есть предложения, как справиться с этой ситуацией?

1 Ответ

1 голос
/ 28 августа 2011

@ rubish Спасибо за помощь, вместе с другими сообщениями stackoverflow у меня теперь есть следующая работа, но я все еще чувствую, что я слишком усложняю вещи или пропускаю некоторую ключевую информацию, но по крайней мере это работает (по большей части).

models / theme.rb

class Theme < ActiveRecord::Base
   attr_accessible #none

   belongs_to :website
   has_many :pages
   has_many :assets, class_name: "ThemeAsset", dependent: :destroy

   has_many :styles, class_name: "AssetStyle", through: :assets, source: :assetable, source_type: "AssetStyle"
   has_many :scripts, class_name: "AssetScript", through: :assets, source: :assetable, source_type: "AssetScript"
 end

models / theme_asset.rb

class ThemeAsset < ActiveRecord::Base
  attr_accessible :assetable

  belongs_to :assetable, polymorphic: true
  belongs_to :theme
end

models / asset_style.rb

class AssetStyle < ActiveRecord::Base
  attr_accessible #none

  has_many :assets, class_name: "ThemeAsset",  as: :assetable
end

models/asset_script.rb

class AssetScript < ActiveRecord::Base
  attr_accessible #none

  has_many :assets, class_name: "ThemeAsset",  as: :assetable
end

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

  • theme.assets показывает все theme_asset строк, с assetable_id и assetable_type

  • Я не могу найти способ по умолчанию показывать только стили или сценарии через theme.assets.scripts, но я думаю, что я мог бы использовать scope для этого, так же, как в моем первоначальном вопросе

  • Если я сделаю theme.styles.create, стиль будет сохранен, но запись не будет добавлена ​​втаблица asset, то есть я не могу найти ее через theme.assets.

  • Единственный способ добавить обе записи - это to использовать theme.assets.create(assetable: theme.styles.new) (упрощенно)

Это правильный путь, и если нет, может ли кто-нибудь построить поверх моего решения?Заранее спасибо.

...