Перенаправление Rails на основе типа пользователя

#ruby-on-rails #ruby-on-rails-3 #authentication #redirect

#ruby-on-rails #ruby-on-rails-3 #аутентификация #перенаправление

Вопрос:

Я изучаю Rails, создавая приложение shop, и у меня возникли небольшие проблемы с перенаправлениями. У меня есть 3 роли в приложении:

  • Покупатель
  • Продавец
  • Администратор

В зависимости от того, какой тип они вошли в систему, как тогда, я хотел бы перенаправить на другую страницу / действие, но по-прежнему показывать один и тот же URL для каждого (http://…/my-account ).

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

Единственный способ, который я могу придумать, — это выполнить несколько действий (например, покупатель, продавец, администратор) в контроллере учетных записей, но это означает, что пути будут выглядеть какhttp://…/my-account/buyer или http://…/my-account/seller и т.д.

Большое спасибо, Роджер

Я поместил свой код ниже:

модели/user.rb

 class User < ActiveRecord::Base
    def buyer?
        return type == 'buyer'
    end

    def seller?
        return type == 'seller'
    end

    def administrator?
        return type == 'administrator'
    end

    ...

end
  

контроллеры /accounts_controller.rb

 class AccountsController < ApplicationController  
   def show
   end
end
  

контроллеры/user_sessions_controller.rb

 class UserSessionsController < ApplicationController
    def new
        @user_session = UserSession.new
    end

    def create
        @user_session = UserSession.new(params[:user_session])

        if @user_session.save
            if session[:return_to].nil?
            # I'm not sure how to handle this part if I want the URL to be the same for each.
                redirect_to(account_path)
            else
                redirect_to(session[:return_to])
            end
        else
            @user_session.errors.clear # Give as little feedback as possible to improve security.
            flash[:notice] = 'We didn't recognise the email address or password you entered, please try again.'
            render(:action => :new)
        end
    end

    def destroy
        current_user_session.destroy
        current_basket.destroy
        redirect_to(root_url, :notice => 'Sign out successful!')
    end
end
  

config/routes.rb

 match 'my-account' => 'accounts#show'
  

Большое спасибо,
Понял

Ответ №1:

В UserSessionsController#create (т. Е.: метод входа в систему) вы могли бы продолжить перенаправление на путь к учетной записи (при условии, что он ведет к AccountsController#show ), а затем отображать разные представления в соответствии с ролью. Т.е.: что-то вроде этого:

 class AccountsController < ApplicationController  
  def show
    if current_user.buyer?
      render 'accounts/buyer'
    elsif current_user.seller?
      render 'accounts/seller'
    elsif current_user.administrator?
      render 'accounts/administrator
    end
  end
end
  

Еще лучше, вы могли бы сделать это по соглашению…

 class AccountsController < ApplicationController  
  def show
    render "accounts/#{current_user.type}"
  end
end
  

Комментарии:

1. Отлично, большое спасибо. Я не знал о функции рендеринга, я думал, что есть только функция redirect_to .

Ответ №2:

Если я правильно понял ваш вопрос, то решение простое.

Вы можете просто вызвать нужный вам метод внутри вашего контроллера. Я делаю это в своем проекте:

 def create
  create_or_update
end

def update
  create_or_update
end

def create_or_update
  ...
end
  

В вашем случае это должно быть:

 def action
  if administrator? then
    admin_action
  elsif buyer? then
    buyer_action
  elseif seller? then
    seller_action
  else
    some_error_action
  end
end
  

Однако вам, вероятно, следует явно вызывать «render» с именем действия в каждом из этих действий.