Ruby on rails 控制器中的问题/混合-变量/方法可见性问题
所以,我有几个控制器,它们处理模型实例列表,一旦我完成了一个控制器,我就决定将它全部转移到重用代码上Ruby on rails 控制器中的问题/混合-变量/方法可见性问题,ruby-on-rails,Ruby On Rails,所以,我有几个控制器,它们处理模型实例列表,一旦我完成了一个控制器,我就决定将它全部转移到重用代码上 module ListController extend ActiveSupport::Concern #code end 但这让我想到了几个问题 首先,我需要这个控制器使用不同的资源。例如: module ListController extend ActiveSupport::Concern included do doll = self.name.to_s.ma
module ListController
extend ActiveSupport::Concern
#code
end
但这让我想到了几个问题
首先,我需要这个控制器使用不同的资源。例如:
module ListController
extend ActiveSupport::Concern
included do
doll = self.name.to_s.match(/^(\w+)ListController/)[1]
@resource = doll.downcase
@klass = doll.singularize.constantize
define_method("new_#{@resource}_list") do
if appropriate_quantity?
quantity=params[:quantity].to_i
array = Array.new(quantity) do
@klass.new
end
instance_variable_set("@#{@resource}", array)
elsif invalid_entry_cookie?
invalid_entries_from_redis(@klass)
else
redirect_to :back
end
end
end
end
因此,当包含模块时,我会得到控制器的名称,在ListController之前查找部件,按照我自己的惯例,它会引导我找到所需的模型和资源:
doll = self.name.to_s.match(/^(\w+)ListController/)[1]#=>Students
@resource = doll.downcase #=>students
@klass = doll.singularize.constantize #=>Student
看起来不错。但是
1) 模块本身看不到实例变量。所以@resource
和@klass
在第行define_method
之后失去了它的可见性,一切都失去了它的意义。我无法使模块具有足够的灵活性,以便在没有变量始终可见的情况下可重用。解决方案
2) 包括在内,我是否将@resource
和@klass
传递给每个控制器?我不喜欢这样,因为他们根本不需要。我想避免这种情况。1)您可以在执行操作之前使用过滤器设置这些实例变量,如下所示:
module ListController
extend ActiveSupport::Concern
included do
# Set instance vars in the current class
init_proc = Proc.new do |c|
doll = c.class.name.match(/^(\w+)ListController/)[1]
c.instance_variable_set(:@resource, doll.downcase)
c.instance_variable_set(:@klass, doll.singularize.constantize)
end
# Run the above proc before each page load this method is declared in
before_action(init_proc)
# Make @resource and @klass available right now
init_proc.call(self)
define_method("new_#{@resource}_list") do
if appropriate_quantity?
quantity=params[:quantity].to_i
array = Array.new(quantity) do
@klass.new
end
instance_variable_set("@#{@resource}", array)
elsif invalid_entry_cookie?
invalid_entries_from_redis(@klass)
else
redirect_to :back
end
end
end
end
2) 您可以在ApplicationController
中包含此类问题,以避免到处都包含