2017-03-22 9 views
0

私はこの問題の良い解決策を見つけたことはありません。私はadmin_content_path(content)を呼び出すときに、私はidは、コンテンツのIDになりたい一方で、私は、idはコンテンツのスラグになりたいcontent_path(content)を呼び出すと同じリソースに対して異なるルートIDを持つ方法

resources :contents 

namespace :admin do 
    resources :contents 
end 

:私は、次のルート構造を有しています。私はちょうどidがモデルに関係しないようにしたいです(実際にはidはモデルのto_paramメソッドの戻り値です)。

私はすべてのルートに対してヘルパーメソッドを定義することを避けたいと思いますが、私の意見では弱い解決策です。

私はadmin_content_path(id: content.id)またはcontent_path(id: content.slug)と書くことができますが、これは実際にはちょうどハックです。また、私は

form_for @content 

を書くことができないので、これは、form_forで特に迷惑ですが、私は通常

form_for @content, url: @content.new_record? ? admin_contents_path : admin_contents_path(id: @content.id) 

答えて

1

を使用するように強制しています、あなたはへのルートを変更します

resources :contents, param: :slug 

とし、to_paramメソッドをオーバーライドすると、次のようになります。

class Content < ApplicationRecord 
    def to_param 
    slug 
    end 
end 

最後に、コントローラではContent.find(params[:id]Content.find_by(slug: params[:slug])に置き換えます。

content_path(content)に電話すると、/contents/foo-barのようなURLが表示されます。 (例えばAdmin::ContentsController)、それはデフォルトでするのではなく、Admin::Contentクラスを使用しますAdminの下に名前空間され、あなたのadmin/contents_controller.rbので

module Admin 
    class Content < ::Content 
    def to_param 
     id && id.to_s # This is the default for ActiveRecord 
    end 
    end 
end 

:あなたのケースでは

、あなたはさらにto_paramメソッドをオーバーライドするサブクラスを作成することができます普通のContentクラスなので、オブジェクト自体とすべてのルートは、フォームを含めて、あなたが好きなものでなければなりません。

+0

こんにちは、素敵な解決策!ありがとうございます – mdesantis

1

ユーザーのフロントエンド側でのリソースのURL生成(slugsを使用)と管理フォームのURL生成という2つの異なる問題があります。

明らかに、あなたの管理者が名前空間になっているので、form_for @resourceと書くことは決してできません。最低でも少なくともform_for [:admin, @resource]になるはずです。

スラグを返すために、あなたがあなたのモデルの一部にto_paramがあるとしましょう、あなたは常に/admin/とレコードのidを使用して名前空間のパスを返すために、あなたの管理者のバックオフィスに独自にカスタマイズしたヘルパーを作成することができます。

これを行う一般的な方法の1つは、この種のコードをAdminルートコントローラに追加することです。

class Admin::AdminController < ApplicationController 

    helper_method :admin_resource_path, :edit_admin_resource_path 

    def admin_resource_path(resource) 
    if resource.new_record? 
     polymorphic_path([:admin, ActiveModel::Naming.route_key(resource)]) 
    else 
     polymorphic_path([:admin, ActiveModel::Naming.singular_route_key(resource)], id: resource.id) 
    end 
    end 

    def edit_admin_resource_path(resource) 
    polymorphic_path([:edit, :admin, ActiveModel::Naming.singular_route_key(resource)], id: resource.id) 
    end 
end 

次に、form_for(@user, url: admin_resource_path(@user)を使用できます。ユーザー作成とユーザー編集の両方で機能します。 コントローラ内のヘルパーを使用してリダイレクトすることができます。

+0

私はすべてのルートのためのヘルパーメソッドを定義することを避けたいと思います – mdesantis

0

まあ、すばらしい解決策を見つけましたが、Rails> = 5.1(現時点でrc1にあります)新しいdirect method

namespace :admin do 
    resources :contents 
end 

# Maps admin content paths in order to use model.id instead of model.to_param 
{ admin_content: :show, edit_admin_content: :edit }.each do |direct_name, action| 
    direct direct_name do |model, options| 
    options.merge(controller: 'admin/contents', action: action, id: model.id) 
    end 
end 
関連する問題