简体   繁体   English

如何在Rails中使模型知道其控制器?

[英]How to make a model aware of its controller in Rails?

I am making a Rails application, and i would like to be able use a model object passed to a view to get the URL of some action on this object, like this, for example: 我正在制作一个Rails应用程序,并且我希望能够使用传递给视图的模型对象来获取对该对象的某些操作的URL,例如:

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

What would be a good way to do this? 什么是做到这一点的好方法? Can it be done with a decorator like Draper ? 可以使用Draper这样的装饰器来完成吗? Are there some examples online? 网上有一些例子吗?


Update. 更新。 I have thought about this and decided that a decorator is not a good place to keep controller information. 我已经考虑过这一点,并决定装饰器不是保存控制器信息的好地方。 It is not decorator's responsibility. 这不是装饰者的责任。 A decorator should only know to render formatted data with markup. 装饰者应该只知道使用标记呈现格式化的数据。 For now i have created a module called Accessor where i try to mix models with controller and routing awareness. 现在,我已经创建了一个称为Accessor的模块,在该模块中我尝试将模型与控制器和路由意识混合在一起。 I still wonder if there is a better way to do. 我仍然想知道是否有更好的方法。

If you don't mind having another instance variable on your view, you can implement this using a very simple class (no need for decorators). 如果您不介意在视图上使用另一个实例变量,则可以使用一个非常简单的类(无需装饰器)来实现。

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

On your controllers: 在您的控制器上:

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

And on your shared view: 在您的共享视图上:

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

Of course, this assumes that the controller you want as target is the same controller that renders the view, which might not be true. 当然,这假设您要用作目标的控制器与呈现视图的控制器相同,但可能并非如此。 Still, using this pattern you can accommodate a more complex logic that suits your needs (having multiple Router classes, for instance), without having to change the view. 不过,使用此模式,您可以容纳更适合您需要的逻辑(例如,具有多个Router类),而不必更改视图。

I've found a very interesting solution in Objects on Rails by Avdi Grimm: Exhibits for REST . 我在Avdi Grimm的《 Objects on Rails》中找到了一个非常有趣的解决方案: REST展览 In short, his idea is to apply multiple Ruby's SimpleDelegator s as decorators with various functions. 简而言之,他的想法是将多个Ruby的SimpleDelegator用作具有各种功能的装饰器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让Nginx了解Rails代码更改 - How to make Nginx be aware of Rails code changes 如何对模型和控制器进行异步调用并在视图中获取其值? - how to make an asynchronous call to model and controller and get its values in views? Rails 4如何为用户(控制器,视图,模型)注册课程 - Rails 4 how to make enrolment to a course for users (controller, view, model) 如何从Rails模型向控制器发出PUT请求? - How to make a PUT request from a Rails model to controller? Rails:如何让Date strftime知道默认的语言环境? - Rails: How to make Date strftime aware of the default locale? Rails误读表结构,如何使其了解当前结构 - Rails misreading table structure, how to make it aware of current strcuture Rails 6:模型可以知道对其 has_many 关联之一所做的更改吗? - Rails 6: Can a model be aware of changes made to one of its has_many associations? 如何在Rails中用另一个控制器覆盖模型控制器 - How to overriding model controller with another controller in Rails 如何杀死控制器模型中存在的线程(Ruby 2.1.2 on Rails 3.2.13) - How to Kill threads that are present in Controller in its model (Ruby 2.1.2 on Rails 3.2.13) 无法在Rails的控制器中访问模型方法 - Cannot access model method inside its controller in Rails
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM