Полиморфные отношения rails и link_to
-
18-09-2019 - |
Вопрос
Вот моя Схема
class Menu < ActiveRecord::Base
belongs_to :menuable, :polymorphic => true
end
class Page < ActiveRecord::Base
has_one :menu, :as => :menuable
end
class Links < ActiveRecord::Base
has_one :menu, :as => :menuable
end
Я хочу создать ссылку на полиморфный класс в представлении меню, используя link_to, например
<%= link_to menu.name, menu.menuable %>
Это работает, но при этом извлекается объект menuable из базы данных, в то время как все, что я хотел, это сгенерировать ссылку.Вы можете себе представить, если мое меню будет большим, это действительно затруднит работу моего приложения.
Когда я определил поле menuable как полиморфное, Rails создал menuable_type и menuable_id.Что я могу использовать для создания ссылки на полиморфную страницу, за исключением написания вспомогательной функции с гигантским оператором switch (напримересли у меня есть большое количество меняемых "подклассов"?)
Решение
Прошло много времени с тех пор, как был задан этот вопрос, но недавно у меня была такая же проблема, и решение состояло в том, чтобы использовать polymorphic_url
.Вам нужно найти название маршрута, на который вам нужно создать ссылку, например "fast_car_path" и создать его из ваших *_type и *_id из полиморфной таблицы.Например, у вас есть список комментариев, и вы хотите создать ссылку на автомобили, которым они принадлежат.Итак , если *_type = FastCar , мы имеем
@comments.each do |comment|
link_to polymorphic_url(comment.commentable_type.tableize.singularize, :id => comment.commentable_id)
который сгенерирует "fast_car_path" без загрузки автомобилей из базы данных.
Я новичок в rails, и я не знаю, насколько хорош этот совет, но я надеюсь, что он будет кому-то полезен.
Другие советы
Вы могли бы сделать что-то вроде этого:
def my_menu_url(menu)
"/#{menu.menuable_type.tableize}/#{menu.menuable_id}"
end
если вы используете соглашение rails для присвоения имен контроллерам, соответствующим вашим моделям.
Но не делай этого.Вы работаете в обход механизма маршрутизации rails, и это просто плохая практика.
Вам следует использовать опцию :включить в свои поисковики, чтобы быстро загрузить свои меню:
Menu.all :include => :menuable
В случае, если этого недостаточно, вы можете использовать какой-то вид кэширования.