Каков лучший способ избежать дублирования кода между представлениями и контроллерами в Ruby on Rails? - PullRequest
3 голосов
/ 18 декабря 2008

У меня в настоящее время есть код в моем ApplicationController, чтобы проверить, вошел ли пользователь в систему и имеет ли он необходимый доступ для выполнения определенного действия (тесты выполняются в before_filter).

Мне требуется та же функциональность в представлениях, чтобы решить, следует ли отображать ссылки администратора в представлении списка, но как мне лучше избежать дублирования кода в контроллерах и представлениях?

То, как я решил сделать это сейчас, это иметь user_can_edit_customers? по сути быть оболочкой для 'can_edit_customers?' в моем классе пользователя:

ApplicationController:

class ApplicationController 

А потом сделайте что-то похожее, на мой взгляд, помощники.

Таким образом, все функции инкапсулированы в модели User, но мне все еще нужно определить оболочки в моих контроллерах и помощниках, но есть ли более разумные способы сделать это?

Обратите внимание, пользовательский материал является лишь примером - это также относится и к другим функциям.

Ответы [ 5 ]

3 голосов
/ 18 декабря 2008

Я бы сказал, что нужно покончить с обертками и просто вызвать can_edit_customers? непосредственно для объекта пользователя, переданного в представление.

Если вы хотите сохранить их, можно использовать helper_method в вашем контроллере.

helper_method :current_user, :can_edit_customers?

def current_user
    @current_user ||= User.find_by_id(session[:user])
end

def can_edit_customers?
    @current_user.can_edit_customers?
end

Таким образом, метод также становится доступным в представлении.

<% if can_edit_customers? -%>...<% end -%>
1 голос
/ 23 декабря 2008

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

Я бы взял другое решение.

Допустим, у нас есть Cucumber, модель, которая не должна редактироваться некоторыми пользователями. Я создаю #editable? метод следующим образом:

class Cucumber < ActiveRecord::Base
  def editable?(current_user)
    # Something happens here.
  end
end

Обратите внимание, что если страница доступна всем, то current_user может иметь значение false.

Затем в представлениях, которые вы можете сделать:

<%- if @cucumber.editable?(current_user) -%>
<%# Something happens here. -%>
<%- end -%>

А в контроллерах используйте фильтр.

Лучшим в этом подходе является то, что он следует Толстая модель и позволяет легко покрыть ваши разрешения с помощью модульных тестов.

1 голос
/ 19 декабря 2008

Просто чтобы быть более прямым. «Макрос» helper_method в контроллере заставляет метод контроллера вести себя так, как если бы он был также методом в помощнике приложения.

helper_method :current_user, :can_edit_customers?
0 голосов
/ 18 декабря 2008

Это общепринятая практика - делать такие методы, как logged_in? доступно в контроллере и просмотрах. В большинстве случаев вам не нужно вдавливать логику авторизации в модели.

Определенно придерживайтесь подхода, описанного пользователем Hates. Посмотрите на плагины, такие как restful_authentication и acts_as_authenticated, чтобы увидеть, как они это сделали.

Существует несколько Railscasts (http://railscasts.com/episodes?search=authentication), охватывающих эту тему. Например, вы можете написать помощник, который принимает блок и затем используется так:

<%- admin_user_ do %>
  <%= link_to .. %>
  <%= link_to .. %>
  <%= link_to .. %>
<%- end %>
0 голосов
/ 18 декабря 2008

Я думаю, что помощники - это способ делать то, что вы хотите. Что касается проверки в представлениях того, имеет ли пользователь право делать что-либо, вы можете установить флажок в данных сеанса (например, session[:admin] = true и проверить это в своем представлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...