2012-10-03 46 views
0

我想提出一個Rails應用程序,並且我希望能夠利用傳遞到視圖的模型對象來獲取一些動作的URL這個對象上,類似這樣的,例如:如何讓模型知道它的控制器在Rails中?

link_to object.public_send(attribute), 
     { :controller => object.controller_path, 
      :action  => :show, 
      :id   => object.id } 

會是什麼是做這個的好方法嗎?它可以用像Draper這樣的裝飾工來完成嗎?網上有一些例子嗎?


更新。我曾想過這個,並決定裝飾者不是一個保存控制器信息的好地方。這不是裝飾者的責任。裝飾者只應該知道用標記呈現帶格式的數據。現在我已經創建了一個名爲Accessor的模塊,我嘗試將模型與控制器和路由意識混合使用。我仍然懷疑是否有更好的方法去做。

+0

你能澄清你爲什麼需要這個嗎?也許這是你可以用[url_for](http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-url_for)做的事情? –

+0

謝謝,這是接近我想要的,但我已經試過了。 'url_for'的大問題是它依賴於['polymorphic_url'](https://github.com/rails/rails/blob/537ede912895d421b24acfcbc86daf08f8f22157/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb#L90),它知道沒有關於模型,並依賴於Inflector來猜測控制器名稱。不能使用自定義名稱。小問題是我可能想讓不同的控制器在不同的情況下管理相同的模型。 – Alexey

+0

你能舉一個你需要這個的例子嗎?看起來你想要多個演示者類,但它可能是矯枉過正,取決於你想要完成什麼 –

回答

0

如果你不介意在你的視圖中有另一個實例變量,你可以使用一個非常簡單的類來實現它(不需要裝飾器)。

class MyRouter 
    def initialize(controller, object) 
    @controller = controller 
    @object  = object 
    end 

    def url_for(action_name) 
    controller.url_for(object, :action => action_name) 
    end 
end 

在你的控制器:

class AController 
    def edit 
    @router = MyRouter.new(self, object) 
    render 'shared_view' 
    end 
end 

class BController 
    def edit 
    @router = MyRouter.new(self, object) 
    render 'shared_view' 
    end 
end 

與您分享的觀點:

<%= @router.url_for(:show) # Varies with the controller that rendered the view %> 

當然,這是假定你想爲目標的控制器是呈現相同的控制器這可能不是真的。儘管如此,使用這種模式,您可以適應更復雜的邏輯,以滿足您的需求(例如,具有多個Router類),而無需更改視圖。

+0

在我的情況下,目標控制器更多依賴於模型類而不是當前控制器,並且可能有多個對象傳遞給視圖,並且每個對象都應該將鏈接指向自己的控制器。 – Alexey

+0

目標控制器對於每個對象有何不同?由控制器確定呈現共享視圖?或者還有另一個標準? –

+0

當前控制器決定哪個「家」控制器與哪些模型類相關聯。但他們在大多數情況下只會依賴於模型類。 – Alexey

0

我在Avdi Grimm的Objects on Rails發現了一個非常有趣的解決方案:Exhibits for REST。簡而言之,他的想法是將多個Ruby的SimpleDelegator作爲具有各種功能的修飾器應用。

相關問題