2012-10-03 48 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作为具有各种功能的修饰器应用。

相关问题