5

次のようなルートがあります。

scope ":department", department: /admin|english|math/, defaults: { department: 'admin' }

このルートのデフォルト部門を に基づいて作成することは可能current_user.department.nameですか?

これが不可能な場合、私の問題を解決する別の方法は何ですか? 問題は、特に明記しない限り、すべてのリンクを現在のスコープにデフォルト設定することです。私は現在、多くの場所で次のことを行っています。

# links to /math/students
link_to 'students', students_path(department: current_user.department.name.downcase)
4

5 に答える 5

6

私が正しく理解していれば、あなたが望むのは次のように書けることです:

link_to 'students', students_path

現在のユーザーに基づいて部門オプションが自動的に設定されます。

これまでに提供された他のソリューションと同様のソリューションを次に示します。部門を必要とする各ルートのヘルパーを定義します。ただし、これはプログラムで行うことができます。

どうぞ: app/helpers/url_helper.rb

module UrlHelper

  Rails.application.routes.routes.named_routes.values.
    select{ |route| route.parts.include?(:department) }.each do |route|
      define_method :"department_#{route.name}_path" do |*args|
        opts = args.extract_options!
        if args.size > 0
          keys = route.parts - [:department]
          opts.merge!(Hash[*keys.zip(args).flatten])
        end
        opts.reverse_merge!(department: current_user.department.name.downcase)
        Rails.application.routes.url_helpers.send(:"#{route.name}_path", opts)
      end
  end

end

これで、パス セグメントを持つすべてのルートのようなヘルパー メソッドがdepartment_students_pathできました。これらは同じように機能します -- opts を渡すことができ、明示的に設定することもでき、デフォルトを上書きします。また、メンテナンスをしなくても、変更が反映された最新の状態を維持できます。:departmentstudents_path:departmentroutes.rb

元のヘルパーと同じ名前を付けることもできます。つまり、

define_method :"#{route.name}_path"

それらにプレフィックスを付ける必要なしに --department_私はそうしませんでした。なぜなら、そのような名前の衝突を避けたいからです。それがどのように機能するかはわかりませんが (ビュー テンプレートから呼び出したときにどのメソッドがメソッド ルックアップを獲得するか)、調べてみてください。

もちろん、ヘルパー メソッドに対してこのブロックを繰り返すことができる_urlので、ヘルパー メソッドに加えてそれらを使用できます_path

ビューだけinclude UrlHelperでなくコントローラーでもヘルパーを使用できるようにするには、ApplicationController.

だから私はこれがあなたの基準を満たしていると思います:

  1. :departmentスコープが の部門にデフォルト設定されるパスのヘルパー メソッドを呼び出すことができるcurrent_userため、これを毎回明示的に指定する必要はありません。
  2. ヘルパーは、セグメントを持つ実際に定義された名前付きルートに基づいてメタプログラミングによって生成される:departmentため、それらを維持する必要はありません。
  3. ビルトインの Rails url_helpers のように、これらの人は他のパス セグメントの位置引数を取ることができますdepartment_student_path(@student)。ただし、1 つの制限として、部門をオーバーライドする場合は、最終的な opts ハッシュ ( ) でオーバーライドする必要がありますdepartment_student_path(@student, department: 'math')。繰り返しになりますが、その場合はいつでも を実行できるstudent_path('math', @student)ので、それほど制限はないと思います。
于 2013-06-14T15:44:57.023 に答える
1

ルート制約は proc を受け入れることができるため、次の「ハック」でこの問題を解決できます。

concern :student_routes do
  # all your routes where you want this functionality
end

# repeat this for all departments
scope ":department", constraints: lambda{|req| req.session[:user_id] && User.find(req.session[:user_id]).department.name.downcase == "english"}, defaults: { department: 'english' } do
  concerns :student_routes
end

ルートの問題は Rails 4 の機能です。Rails 4 を使用しない場合は、 https ://github.com/rails/routing_concerns の gem で機能を利用できます。

学生のすべてのルートをすべてのスコープにコピーすることもできます。

于 2013-06-19T14:19:15.230 に答える
0

ネストされたルートの使用についてはどうですか? これを次のように実装できます。

resources :departments do
  resources :students
end

わかりやすい URL (ID の代わりに「数学」など) を使用する場合は、部門モデルに次を追加できます。

  # in models/department.rb
  def to_param
    name.downcase
  end

名前は部門ごとに一意でなければならないことに注意してください。Ryan B はこれについてrailscastを作成しました。Friendly idのような gem を使用することもできます。

ビューに以下を追加できるようになりました。

# links to /math/students
link_to 'students', department_students_path(current_user.department)

これを頻繁に使用する場合は、ヘルパーを作成します。

# helpers/student_helpers.rb
def students_path_for_current_user
  department_students_path(current_user.department)
end

# in view
link_to 'students', students_path_for_current_user
于 2013-06-18T19:05:25.523 に答える
0

あなたが使用することができます

link_to 'students', polymorphic_path([current_user.department.name.downcase, :students])

これは呼び出します

math_students_path

動作するには、ルートを追加する必要があると思います

scope ':department', as: 'department' do
  ...

askey は次の形式のヘルパーを生成します。department_something_path

その行が長すぎるため、それをヘルパーに抽出できます

# students path taking into account department
def students_path!(other_params = {}, user = current_user)
  polymorphic_path([user.department.name.downcase, :students], other_params)

次に、ビューで使用します

link_to 'students', students_path!
于 2013-06-14T15:39:54.640 に答える