Comments 44
За kaminari спасибо.
Путь к красивому коду протекает через бурелом говнокода ))))
Путь к красивому коду протекает через бурелом говнокода ))))
+4
kaminari судя по тестом сильно медленнее, чем will_paginate, хотя может исправили уже.
0
Есть railscast на эту тему railscasts.com/episodes/254-pagination-with-kaminari
0
Статья направляет человека на верный путь, однако реальность сурова и некоторые вещи просто не укладываются в концепцию REST, к которой строго принуждают эти ваши inherited_resources. Хотя к этому надо стремиться.
0
Давайте примеры. Разберем более предметно.
0
Яркий пример: главная страница сайта (где есть новости, блоги, последние комментарии к чему-либо). В общем где контроллер обращается к более чем одной модели.
P.S. Это, конечно, резко с моей стороны утверждать, что что-то не укладывается в REST — при желании можно уложить почти все, тут вопрос в том, стоит ли овчинка выделки.
P.S. Это, конечно, резко с моей стороны утверждать, что что-то не укладывается в REST — при желании можно уложить почти все, тут вопрос в том, стоит ли овчинка выделки.
0
Проще всего это организовать через before_filter. Вот пример контроллера главной страницы, который как раз показывает новости и последнии комментарии:
class PostsFeedsController < InheritedResources::Base
respond_to :html, :rss, :only => :index
actions :index
before_filter lambda{ @latest_comments = Comment.by_domain(Domain.current_domain).latest(10) }
before_filter lambda{ @latest_posts = Post.by_domain(Domain.current_domain).latest(10) }
caches_page :index, :unless => lambda {|c| c.user_signed_in?}
include Platform::Controllers::Paginate
include Platform::Controllers::Domain
include Platform::Controllers::EagerLoading
end
* This source code was highlighted with Source Code Highlighter.
0
Фильтры кажутся, как бы это сказать, wrong place for that.
В RoR есть какая-нибудь возможность вызвать другой Action из View и поместить его результат в месте вызова?
В RoR есть какая-нибудь возможность вызвать другой Action из View и поместить его результат в месте вызова?
+1
partials
0
Что-то мне подсказывает, что Partials — это не то. Мы же должны передать в Partial данные из «основного» шаблона, разве не так?
0
А, ну тогда cells, но это нестандартный механизм
0
Посмотрел, да, Cells именно для таких сценариев. Странно только, что он нестандартный.
Кстати, они их описывают как mini-контроллеры. А нет ли возможности вызывать один и тот же Action одного и того же контроллера:
— как из браузера напрямую (и тогда будет сформирована страница этого ресурса), и
— из другого View (и тогда результат будет в виде Partial вставлен в «основную» страницу)?
Кстати, они их описывают как mini-контроллеры. А нет ли возможности вызывать один и тот же Action одного и того же контроллера:
— как из браузера напрямую (и тогда будет сформирована страница этого ресурса), и
— из другого View (и тогда результат будет в виде Partial вставлен в «основную» страницу)?
0
есть такое решение:
github.com/sd/embedded-actions
github.com/sd/embedded-actions
0
А почему вы думаете, что тут должен быть один контроллер?
+1
Потому что контроллер — это штука формирующая ответ на запрос. Одно действие — один ответ. Можно конечно выдать скелет страницы в ответе, а блоки с новостями, блогами и т.п. подгружать динамически — по запросу на блок — это тоже вариант. Эдакая система виджетов.
0
«Потому что контроллер — это штука формирующая ответ на запрос. Одно действие — один ответ.»
Я бы так не сказал. Front Controller (независимо от того, как реализован на конкретной платформе) — да, выдает один ответ. А каждый отдельный контроллер вовсе не обязан выдавать только свой результат сразу в браузер пользователя, их можно комбинировать. В ASP.NET MVC это
Я бы так не сказал. Front Controller (независимо от того, как реализован на конкретной платформе) — да, выдает один ответ. А каждый отдельный контроллер вовсе не обязан выдавать только свой результат сразу в браузер пользователя, их можно комбинировать. В ASP.NET MVC это
RenderAction
, уверен, в RoR это делается похожим образом. В выходящий поток (в браузер пользователя) выдается уже полная страница, независимо от того, сколько контроллеров над ней «поработало».0
Тут можно уйти в теорию (что не хотелось бы). Но по-моему концепция формирования одного view несколькими контроллерами — это уже не MVC. Хотя это удобно — спору нет. Кажется cells в Rails делает нечто подобное.
-1
Не, в теорию уходить не нужно. Концепция формирования кусочков View несколькими контроллерами — вполне укладывается в MVC, сохраняется и Separation of Concerns, и паттерн Front Controller, и все прочее. ASP.NET MVC именно так и устроен. И да, это чертовски удобно :)
0
Создайте модель для этого.
0
тут бы как раз очень Engines пригодилось
0
Что за Engines?
0
Refinery CMS очень их использует, это так сказать собранные в один «модуль» MVC кусочки, которые можно вызывать из «центральной» системы :)
refinerycms.com/engines
refinerycms.com/engines
0
Имхо главное правильно разбить логику на сущности. Да, иногда при этом сущности плодятся, но зато потом не возникает проблем с расширением.
0
А при чем тут REST? Если приложение поддерживает этот архитектурный стиль, вовсе не значит, что не может быть эдаких «обобщенных ресурсов» вроде «главной страницы» или какой-нибудь с виджетами и Pagelet-ами.
0
Спасибо, хорошая статья. Вот еще нашел интересную штуку в вики по Devise: github.com/kristianmandrup/cream
Объединяет аутенфикацию юзеров с помощью Devise, распределению ролей и групп через Roles и авторизации через CanCan.
Если буду создавать новый проект, то этот гем будет установлен в первую очередь.
Объединяет аутенфикацию юзеров с помощью Devise, распределению ролей и групп через Roles и авторизации через CanCan.
Если буду создавать новый проект, то этот гем будет установлен в первую очередь.
0
А есть ли практический смысл уменьшать код контроллеров? Его там и так не много, это модели разрастаются до сотен строк, а контроллеры обычно тонкие.
+1
Смысл есть когда в 5 контроллерах 90% кода — это нагенеренный CRUD, а остальные 10% — кастомные before filters.
+2
Ну эстетически будет красивее, да. Но практически толку от этого мало, читаемость кода не повысит (что там читать в сгенерированом контроллере), скорость разработки это не увеличит, а вот если к проекту подключится новый человек не знакомый с методикой, то ему придется потратить какое-то время на то что бы понять принципы.
+2
inherited_resources очень спорный, ни одно приложение (кроме блога за пять минут) не укладывается в стандартный crud-контроллер. А inherited_resources с нестандартным контроллером — это изучение дополнительного API, сложность чтения кода и лишний, достаточно тяжеловесный гем наполненный метапрограмминговой магией. Зачем? Вам трудно написать def edit; ...; end;?
+1
Основные CRUD действия, как правило, остаются. Конечно приходится добавлять и другие, но inherited_resources здесь совсем не мешает, зато дисциплинирует.
Насчет сложности чтения, как с HAML — вопрос привычки.
def edit; ...; end; — написать не сложно, но зачем писать одно и тоже многократно?
Насчет сложности чтения, как с HAML — вопрос привычки.
def edit; ...; end; — написать не сложно, но зачем писать одно и тоже многократно?
-1
Нет, я говорю о том, что дело никогда не ограничивается чистыми методами crud. Т.е. и index и update и пр. методы всегда расширяются: добавляются фильтры, работа с конечными автоматами, да хоть та же пагинация. По большому счету вы всю логику контроллере выносите в before_filter's и приватные методы которые дергаются IR. Это дезориентирует и в конечном счете превращает код в лапшу. Не говоря уже о том, что приходится писать больше кода.
+1
Согласен, inherited_resources — это вещь в стиле «как сделать простые вещи сложными». Если в проекте много однотипных простеньких контроллеров, то в разы лучше будет создать обычный базовый класс контроллера с минимумом магии и метапрограммирования, который идеально подойдёт под потребности конкретного проекта.
А использовать inherited_resources для нетривиальных контроллеров == снижать читабельность кода в разы.
А использовать inherited_resources для нетривиальных контроллеров == снижать читабельность кода в разы.
+1
… заслуживают отдельной статьи
организуете отдельную статью?
+2
UFO just landed and posted this here
Паш, прикольно что статья в топ вышла :)
Твой подход помню, хотя скажу что у меня он не прижился.
Но вот очень понравилось, как ты объединял edit и new views, до сих пор использую.
Твой подход помню, хотя скажу что у меня он не прижился.
Но вот очень понравилось, как ты объединял edit и new views, до сих пор использую.
-3
Sign up to leave a comment.
Архитектура контроллеров: простые советы на каждый день