Размещение логики представления в контроллере — хорошая практика в Ruby?

StackOverflow https://stackoverflow.com//questions/11681347

Вопрос

Некоторые рекомендации [1] предлагают вам использовать

<%= current_user.welcome_message %>

вместо

<% if current_user.admin? %>
  <%= current_user.admin_welcome_message %>
<% else %>
  <%= current_user.user_welcome_message %>
<% end %>

Но проблема в том, что где-то в вашем коде должна быть логика принятия решений.

Насколько я понимаю, решение принимается template Это лучше чем controller так как это сделает ваш контроллер более чистым.Это правильно?

Есть ли лучший способ справиться с этим?

http://robots. Thoughtbot.com/post/27572137956/tell-dont-ask

Это было полезно?

Решение

По моему мнению, если текст — единственное, что меняется, он не принадлежит представлению.Если вам нужно было реструктурировать страницу, это логика представления.Это просто данные разные.

Другие советы

Вы не первый, кто задается этим вопросом.Если представления и контроллеры практически не должны иметь логики, а модель должна быть независимой от представления, то какое место принадлежит логике представления?

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

Дрейпер — отличный драгоценный камень, который помогает определить декораторов.

Приведенный вами пример кода можно абстрагировать следующим образом:

Передайте декоратор в представление с помощью @user = UserDecorator.new current_user в вашем контроллере.

Ваш декоратор может выглядеть, как показано ниже.

class UserDecorator
  decorates :user

  def welcome_message
    if user.admin?
      "Welcome back, boss"
    else
      "Welcome, #{user.first_name}"
    end
  end
end

И ваше представление будет просто содержать @user.welcome_message

Обратите внимание, что сама модель не содержит логики для создания сообщений.Вместо этого декоратор оборачивает модель и переводит данные модели в презентабельную форму.

Надеюсь это поможет!

Я бы использовал для этого помощника.Предположим, вам нужно перевести приветственное сообщение на основе некоторой локали.

в app/helper/user_helper.rb писать

module UserHelper

  def welcome_message(user)
    if user.admin?
      I18n.t("admin_welcome_message", :name => user.name)
    else
      I18n.t("user_welcome_message", :name => user.name)
    end
  end 

end

и, по вашему мнению, вы можете просто написать

<%= welcome_message(user) %>

Обратите внимание, что декоратор/презентатор предлагает действительно чистый объектно-ориентированный подход, но, по моему мнению, использование помощника намного проще и достаточно.

Нет, ты не хочешь любой условные обозначения вообще ни в классе пользователя, ни в контроллере.Целью этого примера в блоге является ссылка на полиморфизм, просто старый добрый объектно-ориентированный дизайн.

# in application_controller for example
def current_user
  if signed_in?
    User.find(session[:user_id])
  else
    Guest.new
  end  
end

#app/models/user.rb
class User
   def welcome_message
     "hello #{name}"
   end
end

#app/models/guest.rb
class Guest
  def welcome_message
    "welcome newcomer"
  end
end

... вы поняли.

Только вместо того, чтобы засорять вашу модель методами, предназначенными только для представления, создайте декоратор, который действует как презентатор:

require 'delegate'
class UserPresenter < SimpleDelegator
  def welcome_message
    "hello #{name}"
  end
end

И сейчас current_user выглядит так:

# application_controller
def current_user
  if signed_in?
    UserPresenter.new(User.find(session[:user_id]))
  else
    Guest.new
  end
end

Украсьте модель пользователя и добавьте к ней Welcome_message напрямую.Да, в какой-то момент это может включать в себя какое-то условное утверждение.

http://robots. Thoughtbot.com/post/14825364877/evaluating-alternative-decorator-implementations-in

Я думаю, вам стоит посмотреть выпуск Railscasts на Presenters, чтобы получить ответ.

Логику представления сложно поддерживать, мы должны поместить бизнес-логику в модель, а всю логику представления — в помощники.

Если вы хотите, чтобы ваш код был объектно-ориентированным, используйте декораторы (объектно-ориентированный способ помощников).

Лучший пример: https://github.com/jcasimir/draper

Поместите код, определяющий current_user.welcome_message в _app/helpers/application_helper.rb_ оно будет доступно любому представлению, отображаемому с помощью приложение макет.

Другой вариант — определить обычай вспомогательный модуль, который не обязательно связан с данным представлением или контроллером (см. видео, ссылку на которое я дал ниже), и include это в модулях представления/контроллеров, в которых вы хотите иметь эту функциональность.

Это не что-то черно-белое.Но из того, что вы описали, похоже, что это код, который сложно вставлять в ваш application_controller.rb, и это не код с функциональностью, которая оправдывает наличие собственного контроллера, наиболее эффективным и действенным вариантом может быть создание собственного вспомогательного модуля. и включите его в помощники, в которых вы хотите иметь эту функциональность.Тем не менее, в конечном итоге это решение, которое принимает разработчик приложения (т. ты) необходимо принять решение.

Здесь — хорошая статья, описывающая вспомогательные модули из Май, 2011 г.

Здесь это описание RailsCast обычай вспомогательные модули (т.е.пользовательские, например модули, не обязательно связанные с данным контроллером или представлением).Коротко, мило и по делу.

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

Хорошей практикой было бы иметь реальные View экземпляры.Rails пародия на MVP (есть разница, посмотрите), к сожалению, похоже, делает вид, что представления являются шаблонами.Это не правильно.

Предполагается, что представления содержат логику представления в шаблонах MVC и MVC.Они также должны манипулировать несколькими шаблонами и принимать решения о том, какие шаблоны использовать для представления состояния и информации с уровня модели (да, модель — это уровень, а не экземпляр ORM).

Итак, чтобы ответить на вопрос: Логике представления нет места в контроллерах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top