2010-08-22 79 views
4

我有幾個不同的用戶類型(買家,賣家,管理員)。Rails根據用戶類型呈現不同動作和視圖的方式?

我希望他們都擁有相同的account_path URL,但要使用不同的操作和視圖。

我想這樣的事情...

class AccountsController < ApplicationController 
    before_filter :render_by_user, :only => [:show] 

    def show 
    # see *_show below 
    end 

    def admin_show 
    ... 
    end 

    def buyer_show 
    ... 
    end 

    def client_show 
    ... 
    end 
end 

這是我在如何定義ApplicationController的... render_by_user

def render_by_user 
    action = "#{current_user.class.to_s.downcase}_#{action_name}" 
    if self.respond_to?(action) 
     instance_variable_set("@#{current_user.class.to_s.downcase}", current_user) # e.g. set @model to current_user 
     self.send(action) 
    else 
     flash[:error] ||= "You're not authorized to do that." 
     redirect_to root_path 
    end 
    end 

它要求在控制器中的正確* _show方法。但仍然試圖呈現「show.html.erb」,並沒有尋找我在那裏命名爲「admin_show.html.erb」「buyer_show.html.erb」的正確模板等。

我知道我可以只需在每個動作中手動撥打render "admin_show",但我認爲在過濾器之前可能會有更乾淨的方法來完成此操作。

或者有其他人看過插件或更優雅的方式來分解動作&按用戶類型查看?謝謝!

順便說一句,我使用的Rails 3(萬一它有所作爲)。

+0

除了裝載有獨特的見解,有沒有在每個動作的邏輯多大差別? – 2010-08-22 19:37:50

+1

是的每個控制器將會有很大的不同。可能應該提到這一點。 – 2010-08-22 22:45:26

回答

4

根據視圖模板是多麼的不同,它可能是有益的一些這個邏輯移入show模板,而不是做開關有:

<% if current_user.is_a? Admin %> 
<h1> Show Admin Stuff! </h1> 
<% end %> 

但是,爲了回答你的問題,你需要指定要渲染的模板。如果你設置你的控制器的@action_name這應該工作。你可以在你的render_by_user方法做到這一點,而不是使用本地action變量:

def render_by_user 
    self.action_name = "#{current_user.class.to_s.downcase}_#{self.action_name}" 
    if self.respond_to?(self.action_name) 
    instance_variable_set("@#{current_user.class.to_s.downcase}", current_user) # e.g. set @model to current_user 
    self.send(self.action_name) 
    else 
    flash[:error] ||= "You're not authorized to do that." 
    redirect_to root_path 
    end 
end 
+0

是的 - 它是有道理的,但希望有一種方法可以在過濾器之前完全在'r​​ender_by_user'中完成。感謝帖子! – 2010-08-23 02:53:58

+0

@Brian,爲您更新建議:見上文! – 2010-08-23 16:24:42

+0

哦酷!不知道你可以像這樣設置action_name。是的,這看起來像贏家。會試試看! – 2010-08-23 18:31:45

相關問題