Rails - 控制器如何将实例变量传递给Views ...它可以被停止吗?

时间:2013-09-12 19:51:13

标签: ruby-on-rails ruby

我理解并理解通过将@放在Controller中的变量名前面,它在任何View加载时都可用。这非常有用,但我想了解它的魔力。它是如何发生的,可以停止吗?

我正在尝试使用继承来干燥我的CRUDdy资源控制器,将大部分逻辑放在ApplicationController中。超类应引用抽象变量@resource(对于单个资源),@resources(对于资源集合)和@parent_resource(对于@resource时的父资源是嵌套的),但理想情况下,视图会获得更具体的名称,例如分别为@customer@customers@sales_territory。可以在不将所有对象(一次在抽象名称中,一次在具体名称中)的重复项发送到视图的情况下完成此操作?

在我写这篇文章时,想到的可能性是;

  1. 受保护的实例变量...... Ruby有这样的东西,并且 如果是这样,那么Controller会把它们交给View吗?
  2. 在render / redirect
  3. 之前将通用命名变量设置为nil
  4. 使用子类中定义的受保护的空方法代替 抽象命名实例变量
  5. 如何实现这一目标的正确选择是什么?

1 个答案:

答案 0 :(得分:5)

我假设在这里发生的事情是,你的应用程序中有一堆控制器,它们只是做同样的事情,因此你想利用继承来干掉它。

话虽这么说,我不完全确定ApplicationController是转发所有这些功能的正确位置,如果您拥有新的控制器,它们也将继承所有这些功能而不需要它。

我会做这样的事情:

  • 假设你有这样的控制器:
    • lions_controller.rb
    • tigers_controller.rb
    • hippos_controller.rb

他们几乎有类似的功能......我会创建一个“Base”控制器,然后在子控制器上设置继承。然后我还会做一个动作来设置子控制器的“逻辑”默认值,就像这样。

AnimalsController.rb

class AnimalsController < ApplicationController
  class_attribute :resource_class, :parent_resource_class

  protected
    def self.set_resource_attributes(options={})
       self.resource_class = options[:resource_class]
       self.parent_resource_class = options[:parent_resource_class]
    end
end

LionsController.rb

class LionsController < AnimalsController
  #call methods in AnimalsController here, start with setting the resource name
  set_resource_attributes :resource_class => Lion, :parent_resource_class => Animal
end

依此类推......另一件可能有用的事情是使用方法“instance_variable_set”,这样你就可以在视图中设置实际有意义的实例变量名...你可以制作使用你刚刚设置的类变量来执行此操作...例如,让我们重新打开AnimalsController.rb类:

class AnimalsController < ApplicationController
  def show
    instance_variable_set("@#{self.resource_class.name.underscore}".to_sym, self.resource_class.find(params[:id]))
    #... all the regular show stuff
  end
end

这样,当您转到狮子会#how path时,您将在视图中获得的是一个名为@lion的变量,该变量将被设置并包含通过ActiveRecord找到的Lion类的实例。

当然,我在这里投入的伪代码可以清理干净,但是希望你能得到它的位置。希望这会有所帮助。