- Есть множество страниц модели - Page
- Каждая страница может иметь много Widget
- Каждый Widget может находиться на многих страницах Page
- Widget имеет поле element, которое может быть любым объектом, имеющим связь has_one :widget, as: :element
- В данном примере существует два объекта с такими связями: Text и Picture
- Объекты Widget могут иметь множество атрибутов WidgetAttr
- WidgetAttr имеет поля name, atype и value, где atype - некий пользовательский тип, с которым можно будет работать во вьюхе при отображении виджета, остальные поля без комментариев
[1] pry(main)> p2 = Page.create! title: 'Page 2'
=> #<Page:0x007fb468077460
id: 4,
title: "Page 2"
[3] pry(main)> t1 = Text.new body: 'text 111'
=> #<Text:0x000000049a75a0 id: nil, body: "text 111", created_at: nil, updated_at: nil>
[4] pry(main)> pic1 = Picture.new url: 'http://localhost/pic1.png'
=> #<Picture:0x000000048c4de0 id: nil, url: "http://localhost/pic1.png", created_at: nil, updated_at: nil>
[5] pry(main)> p2.widgets.create! element: t1
=> #<Widget:0x000000047ecb48
id: 5,
name: nil,
element_type: "Text",
element_id: 4
[6] pry(main)> p2.widgets.create! element: pic1
=> #<Widget:0x000000045dc588
id: 6,
name: nil,
element_type: "Picture",
element_id: 4
[7] pry(main)> p2.widgets
=> [#<Widget:0x000000047ecb48
id: 5,
name: nil,
element_type: "Text",
element_id: 4
#<Widget:0x000000045dc588
id: 6,
name: nil,
element_type: "Picture",
element_id: 4
[9] pry(main)> p2.widgets[0].element
=> #<Text:0x000000049a75a0
id: 4,
body: "text 111",
Если во вьюхе или в контроллере вызвать render p2.widgets[0].element, то контроллер определит тип объекта, найдет соответствующий ему партиал и отрисует его.
В данном примере показаны ошибки, потому что я не делал вьюхи с партиалами для данных объектов, но суть в том, что если бы они были, рельса нашла бы их и отрисовала
[20] pry(main)> ApplicationController.renderer.render p2.widgets[1].element
ActionView::MissingTemplate: Missing partial pictures/_picture ...
[21] pry(main)> ApplicationController.renderer.render p2.widgets[0].element
ActionView::MissingTemplate: Missing partial texts/_text ...
[28] pry(main)> p2.widgets[1].widget_attrs.create! name: 'x', atype: 0, value: '1'
=> #<WidgetAttr:0x007fb468227cd8
id: 3,
widget_id: 1,
name: "x",
value: "1",
atype: 0
[29] pry(main)> p2.widgets[1].widget_attrs.create! name: 'y', atype: 0, value: '20'
=> #<WidgetAttr:0x007fb4740eeae0
id: 4,
widget_id: 1,
name: "y",
value: "20",
atype: 0