7

私のアプリケーションには、「ユーザー」モデルがあります。各ユーザーは、モデル「アドレス」で定義されている複数の (電子メール) アドレスを持つことができます。

Class User < ActiveRecord::Base
  has_many :addresses


  def is_authorized(op)
     # returns true or false
  end

  def is_owned_by(user)
     # returns true or false
  end
end

Class Address < ActiveRecord::Base
  belongs_to :user
end

AddressController クラス内では、現在ログインしているユーザーが "@user" インスタンス変数で利用できます。コントローラーは、通常のユーザーが自分に属していないアドレスを編集、削除、表示などできないようにしますが、管理ユーザーがそれらを編集することは許可します。AddressController クラスは、現在ログインしているユーザーが通常の操作を実行しているか、スーパーユーザーの操作を実行しているかを AddressModel に問い合わせることができます。

これはすべてうまく機能し、データベースの更新は期待どおりに行われますが、操作モードに応じて異なる HTML ビューが必要です。それを達成するための2つの方法しか考えられません。

  1. (@privileged などのインスタンス変数を使用して) AddressController クラスで認識される操作モード (通常/特権) を作成し、ビューで「if」ステートメントを使用します。
  2. アドレス コントローラーで「after_filter」などを使用して、別のレイアウトをレンダリングします。

単一のコントローラーを実行した結果を、その操作モードに応じて 2 つのまったく異なるレイアウトで表示できる場合、それを実現するための良い方法は何ですか?

前もってありがとうステファン

4

5 に答える 5

10

アクション自体でアクションの結果を表示するために使用するビューを指定できます。使用するレイアウトを指定することもできます。たとえば、次のようになります。

def my_action
  if @user.is_authorised(...)
    render :action => 'admin_action', :layout => 'admin'
  else
    render :action => 'non_admin_action', :layout => 'non_admin'
  end
end

これは、 からの戻り値に応じてadmin_action.html.erbまたはのいずれかをレンダリングします。オプションは、ええと、オプションであり、ビュー/レイアウトのレイアウトを参照します。render のドキュメントで見つけることができる render 呼び出しには、他にもさまざまなオプションがあります。non_admin_action.html.erbis_authorised:layout

于 2009-08-24T13:08:19.137 に答える
7

特定のコントローラーのビューのレイアウト、またはアプリケーション コントローラー内のアプリケーション全体を次の方法で指定できます。

class SomeController < ApplicationController
  layout :set_layout

  def set_layout
    @user.is_authorized(...) ? "privileged_layout" : "normal_layout"
  end

  ...
end

ここでそれを理解しようとすることができます: http://guides.rubyonrails.org/layouts_and_rendering.html#using-renderの2.2.12 Finding Layoutsの下

これが役立つことを願っています=)

于 2009-08-24T14:03:28.700 に答える
4

コントローラー アクションの最後にrenderメソッドを手動で呼び出すだけです。

if @privileged
    render :action => 'show_privileged'
else
    render :action => 'show'
end

app/views/myview/show_privileged.html.erbこれにより、またはがレンダリングされますapp/views/myview/show.html.erb。または、オプションを使用し:templateて明示的なテンプレート ファイルを render メソッドに渡すこともできます。

于 2009-08-24T13:05:57.047 に答える
2

これがアプリ内の唯一のコントローラーであり、あらゆる場所で if/else'ing を行っている場合は、おそらく問題ありません。このタイプのロジックをあらゆる場所で実行し始めると、一度にやりすぎていることがわかります。

あなたが受け入れた答え(これは問題なく機能します!)には、異なるレイアウトと異なるビューがあります。私には、コントローラーがやりすぎていると言っています-これを管理コントローラーに分割します。

于 2009-08-24T18:16:09.257 に答える
1

管理アクションを管理名前空間に配置し、そこで制限する必要があります。controllers ディレクトリにというディレクトリを作成しadmin、そこに _application_controller.rb_ を追加します。

class Admin::ApplicationController < ApplicationController
  before_filter :check_authorized

  private
    def check_authorized?
      if !logged_in? || !current_user.admin?
        flash[:notice] = "You've been very bad. Go away.
        redirect_to root_path
      end
    end
 end

これで、コントローラーをこの名前空間に配置して、コントローラーを継承させることがAdmin::ApplicationControllerできます。

于 2009-08-24T19:18:19.070 に答える