Ruby on rails Rails-控制器如何将实例变量传递给视图…可以停止吗?

Ruby on rails Rails-控制器如何将实例变量传递给视图…可以停止吗?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我理解并欣赏在控制器中变量名前面加上@,无论加载什么视图,它都是可用的。这是非常有用的,但我想了解它的魔力。它是如何发生的,它能被阻止吗 我正在尝试使用继承来干燥粗糙的资源控制器,将大部分逻辑放在ApplicationController中。超类应该引用抽象变量@resource(对于单个资源)、@resources(对于资源集合)和@parent\u resource(对于嵌套了@resource的父资源),但理想情况下,视图会得到更具体的名称,例如@customer、@customers、和

我理解并欣赏在控制器中变量名前面加上@,无论加载什么视图,它都是可用的。这是非常有用的,但我想了解它的魔力。它是如何发生的,它能被阻止吗

我正在尝试使用继承来干燥粗糙的资源控制器,将大部分逻辑放在
ApplicationController
中。超类应该引用抽象变量
@resource
(对于单个资源)、
@resources
(对于资源集合)和
@parent\u resource
(对于嵌套了
@resource
的父资源),但理想情况下,视图会得到更具体的名称,例如<分别编码>@customer、
@customers
、和
@sales\u territory
。这是否可以在不向视图发送所有对象的副本(一次在抽象名称中,一次在具体名称中)的情况下完成

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

  • 受保护的实例变量…Ruby有这样的功能吗 如果是这样,控制器是否会将它们交给视图
  • 在呈现/重定向之前将通用命名变量设置为nil
  • 使用子类中定义的受保护的空方法来代替 抽象命名实例变量

  • 在如何实现这一点上,什么是正确的选择?

    我假设这里正在发生的是,你的应用程序中有一堆控制器,它们实际上只是做同样的事情,所以你想利用继承来消除它

    也就是说,我不完全确定ApplicationController是否适合转储所有这些功能,因为在将来,如果您有新的控制器,它们也会继承所有这些功能,而不一定需要它

    我会这样做:

    • 假设您有这样的控制器:
      • 狮子王控制器.rb
      • 老虎控制器.rb
      • 河马控制器.rb
    它们的功能非常相似。。。我将创建一个“基本”控制器,然后在子控制器上设置继承。然后,我还会做一个动作,设置子控制器的“逻辑”默认值,类似这样的事情

    动物控制器.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
    
    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
    
    class AnimalsController
    LionsController.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
    
    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
    
    class LionControllerLion,:父资源类=>Animal
    结束
    
    诸如此类。。。另一件可能有用的事情是使用“instance\u variable\u set”方法,以便您可以在视图中设置实际有意义的实例变量名。。。您可以使用刚刚设置的类变量来执行此操作。。。例如,让我们重新打开animalcontroller.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
    
    class AnimalsController
    这样,当您转到lions#show路径时,您将在视图中访问名为
    @lion
    的变量,该变量将被设置并包含通过ActiveRecord找到的lion类的实例


    当然,我在这里抛出的这个伪代码可以被清理和干燥一点,但希望你能理解我的意图。希望这能有所帮助。

    我假设在这里发生的是,你的应用程序中有一堆控制器,它们实际上只是做同样的事情,所以你想利用继承来消除它

    也就是说,我不完全确定ApplicationController是否适合转储所有这些功能,因为在将来,如果您有新的控制器,它们也会继承所有这些功能,而不一定需要它

    我会这样做:

    • 假设您有这样的控制器:
      • 狮子王控制器.rb
      • 老虎控制器.rb
      • 河马控制器.rb
    它们的功能非常相似。。。我将创建一个“基本”控制器,然后在子控制器上设置继承。然后,我还会做一个动作,设置子控制器的“逻辑”默认值,类似这样的事情

    动物控制器.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
    
    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
    
    class AnimalsController
    LionsController.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
    
    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
    
    class LionControllerLion,:父资源类=>Animal
    结束
    
    诸如此类。。。另一件可能有用的事情是使用“instance\u variable\u set”方法,以便您可以在视图中设置实际有意义的实例变量名。。。您可以使用刚刚设置的类变量来执行此操作。。。例如,让我们重新打开animalcontroller.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
    
    class AnimalsController
    这边,当你