0

リソースの ID としてテキスト パーマリンクを使用して、Rails アプリのルート用に RESTful なセットアップを行いました。

さらに、名前付きリソースと重複する特別な名前付きルートもいくつかあります。

# bunch of special URLs for one off views to be exposed, not RESTful
map.connect '/products/specials', :controller => 'products', :action => 'specials'
map.connect '/products/new-in-stock', :controller => 'products', :action => 'new_in_stock'

# the real resource where the products are exposed at
map.resources :products

Productモデルはpermalink_fuを使用して名前に基づいてパーマリンクを生成しProductsController、アクセス時にパーマリンク フィールドを検索します。それはすべてうまくいきます。

ただし、データベースに新しいレコードを作成するときに、生成されたパーマリンクが特別な URL と重複していないProductことを検証したいと考えています。

specialsユーザーがまたはまたはnew-in-stockのような通常の Rails RESTful リソース メソッドを作成しようとした場合、コントローラーでルーティング構成を検索し、モデル オブジェクトにエラーを設定し、新しいレコードの検証に失敗し、保存しないようにします。newedit

既知の不正なパーマリンク名のリストをハード コードすることもできますが、その方法では面倒です。ルーティングにフックして自動的に行うことをお勧めします。

(無実を保護し、回答しやすいようにコントローラーとモデルの名前を変更しました。実際の設定はこの例よりも複雑です)

4

3 に答える 3

1

まあ、これは機能しますが、それがどれほどきれいかはわかりません。主な問題は、コントローラー/ルーティング ロジックをモデルに混在させることです。基本的に、モデルにカスタム検証を追加して確認できます。これは文書化されていないルーティング方法を使用しているため、今後どれだけ安定するかわかりません. 誰かがより良いアイデアを持っていますか?

class Product < ActiveRecord::Base
  #... other logic and stuff here...

  validate :generated_permalink_is_not_reserved

  def generated_permalink_is_not_reserved
    create_unique_permalink # permalink_fu method to set up permalink
    #TODO feels really ugly having controller/routing logic in the model. Maybe extract this out and inject it somehow so the model doesn't depend on routing
    unless ActionController::Routing::Routes.recognize_path("/products/#{permalink}", :method => :get) == {:controller => 'products', :id => permalink, :action => 'show'}
      errors.add(:name, "is reserved")
    end
  end
end
于 2009-07-14T00:59:13.600 に答える
0

このような理由から、自分で URI を明示的に管理し、不要なルートを誤って公開しないようにすることをお勧めします。

于 2009-07-21T21:13:12.507 に答える
0

他では存在しないルートを使用できます。この方法では、誰かがタイトルに予約語を選択してもしなくても、何の違いもありません。

map.product_view '/product_view/:permalink', :controller => 'products', :action => 'view'

そしてあなたの見解では:

product_view_path(:permalink => @product.permalink)
于 2009-07-14T01:09:23.667 に答える