Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何从其他类(控制器外部)调用send_data和send_file_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 如何从其他类(控制器外部)调用send_data和send_file

Ruby on rails 如何从其他类(控制器外部)调用send_data和send_file,ruby-on-rails,ruby,Ruby On Rails,Ruby,如何从其他类(控制器外部)调用send_data和send_file 例如,在我的索引控制器中,我已经发送了\u文件和/或发送了\u数据。我想从我自己的特殊班级给他们打电话 我在这个类中有一些代码,希望在不公开任何内容的情况下继续使用相同的方法 样本: app/controller/index\u controller.rb: ... def index t = TestClass.new t.do_something end ... app/package/test\u clas

如何从其他类(控制器外部)调用send_data和send_file

例如,在我的索引控制器中,我已经发送了\u文件和/或发送了\u数据。我想从我自己的特殊班级给他们打电话

我在这个类中有一些代码,希望在不公开任何内容的情况下继续使用相同的方法

样本:

app/controller/index\u controller.rb:

...
def index
   t = TestClass.new
   t.do_something
end
...
app/package/test\u class.rb

class TestClass
   def do_something
      send_file params... # GIVES ERROR BECAUSE THIS IS NOT A RAILS CONTROLLER.
   end
end

有没有办法从这个类调用send_file/send_data?有办法通过这个方法吗?如果可能,怎么做?如果可能,但不推荐,原因是什么?

可能,但不推荐。为什么?因为
send_data
send_file
控制器存在的原因!这是他们的目的之一:解析输入并生成响应

但是如果我坚持呢? 最简单的方法是将对控制器的引用注入到类中。这样的办法应该行得通

def index
  t = TestClass.new(self)
  t.do_something
end

class TestClass
  attr_reader :controller

  def initialize(controller)
    @controller = controller
  end

  def do_something
    controller.send_file(...)
  end
end

这是可能的,但不推荐。为什么?因为
send_data
send_file
控制器存在的原因!这是他们的目的之一:解析输入并生成响应

但是如果我坚持呢? 最简单的方法是将对控制器的引用注入到类中。这样的办法应该行得通

def index
  t = TestClass.new(self)
  t.do_something
end

class TestClass
  attr_reader :controller

  def initialize(controller)
    @controller = controller
  end

  def do_something
    controller.send_file(...)
  end
end

虽然Ruby中的大多数功能都是可行的,但您确实不应该在控制器之外调用send_file,因为它破坏了rails的MVC结构。如果你沿着这条路走下去,你会让任何看你的代码的人感到困惑,包括你未来的自己,你的项目可能会变得越来越不可维护

如果希望有一个助手方法来提供要发送的数据,然后进行一些清理,可以使用块来实现:

class TestClass
  def do_something
    #set up params
    yield params
    #clean up or do other work
  end
end

class IndexController < ApplicationController
  def index
    t = TestClass.new
    t.do_something |params|
      send_file params
    end
  end
end
class测试类
做点什么
#设置参数
屈服参数
#清理或做其他工作
结束
结束
类索引控制器<应用程序控制器
def索引
t=TestClass.new
t、 做点什么|
发送文件参数
结束
结束
结束

虽然Ruby中的大多数功能都是可行的,但您确实不应该在控制器之外调用send_file,因为它破坏了rails的MVC结构。如果你沿着这条路走下去,你会让任何看你的代码的人感到困惑,包括你未来的自己,你的项目可能会变得越来越不可维护

如果希望有一个助手方法来提供要发送的数据,然后进行一些清理,可以使用块来实现:

class TestClass
  def do_something
    #set up params
    yield params
    #clean up or do other work
  end
end

class IndexController < ApplicationController
  def index
    t = TestClass.new
    t.do_something |params|
      send_file params
    end
  end
end
class测试类
做点什么
#设置参数
屈服参数
#清理或做其他工作
结束
结束
类索引控制器<应用程序控制器
def索引
t=TestClass.new
t、 做点什么|
发送文件参数
结束
结束
结束

我不同意“不要这样做”的回答

Presenter模式的全部功能是在控制器外部进行渲染。Sergio Tulentsev的答案(与Presenter模式一致)在单个请求周期的上下文中运行时效果良好

有时,您需要在单个请求周期之外进行操作(正如DHH自己所提到的)。在这种情况下,可以使用链接线程中讨论的方法


我经常两者都用

我不同意“不要做”的回答

Presenter模式的全部功能是在控制器外部进行渲染。Sergio Tulentsev的答案(与Presenter模式一致)在单个请求周期的上下文中运行时效果良好

有时,您需要在单个请求周期之外进行操作(正如DHH自己所提到的)。在这种情况下,可以使用链接线程中讨论的方法


我经常两者都用

我喜欢@eiko所展示的方法,因为它正确地将发送数据保存在控制器中,但让复杂性存在于其他地方。对于其他想采用这种方法但不确定具体块实现的人(起初我不是),下面是我的结论。在控制器内:

respond_to do |format|
  format.pdf do
    exporter = EventRequirementExporter.new(@event_requirement)
    exporter.export_pdf do |data, filename, mime_type|
      send_data data, filename: filename, type: mime_type, disposition: 'attachment'
    end
  end
end
在EventRequirementExporter中:

def export_pdf
  pdf_combiner = CombinePDF.new
  # (buncha stuff happens)
  yield pdf_combiner.to_pdf, combined_filename(:pdf), 'application/pdf'
end

操作部分是收益率,它按照块中提供的顺序填充相关变量。HTH某人。

我喜欢@eiko所展示的方法,因为它正确地将发送数据保留在控制器中,但让复杂性存在于其他地方。对于其他想采用这种方法但不确定具体块实现的人(起初我不是),下面是我的结论。在控制器内:

respond_to do |format|
  format.pdf do
    exporter = EventRequirementExporter.new(@event_requirement)
    exporter.export_pdf do |data, filename, mime_type|
      send_data data, filename: filename, type: mime_type, disposition: 'attachment'
    end
  end
end
在EventRequirementExporter中:

def export_pdf
  pdf_combiner = CombinePDF.new
  # (buncha stuff happens)
  yield pdf_combiner.to_pdf, combined_filename(:pdf), 'application/pdf'
end

操作部分是收益率,它按照块中提供的顺序填充相关变量。HTH某人。

由于这两个答案,我不会从控制器外部调用它。所以我将公开我的对象(只有必要的对象)并在控制器中使用它们。这两个答案对我来说都没问题。但这已经是我想要的了,而且是另外一个。所以我接受这一点。由于这两个答案,我不会从控制器外部调用它。所以我将公开我的对象(只有必要的对象)并在控制器中使用它们。这两个答案对我来说都没问题。但这已经是我想要的了,而且是另外一个。所以我接受这一点。由于这两个答案,我不会从控制器外部调用它。因此,我将公开我的对象(仅必要的对象)并在控制器中使用它们。由于这两个答案,我不会从控制器外部调用它。所以,我将公开我的对象(仅必要的对象)并在控制器中使用它们。是的,演示者很好。不过,这样做是一回事,因为您有演示者,当您将呈现代码与某些业务逻辑“仅仅因为”放在同一堆中时,情况就完全不同了。如果是后者,那么“不要这样做”:(还有,什么样的礼物