如何使一个方法可用于 Rails 中的控制器和模型?

2024-01-31

我的 Rails 应用程序中有一个私有方法来连接到 Amazon S3,执行传递的代码块,然后关闭与 S3 的连接。看起来是这样;

def S3
  AWS::S3::Base.establish_connection!(
    :access_key_id     => 'Not telling',
    :secret_access_key => 'Really not telling'
  )
  data = yield
  AWS::S3::Base.disconnect
  data
end

它是这样调用的(作为示例);

send_data(S3 {AWS::S3::S3Object.value("#{@upload_file.name}",'bucket')}, :filename => @upload_file.name)

我在控制器和模型中以多种方式调用此方法,因此将其作为私有方法包含在两个类中。这个效果很好,我很满意,但它不是很干。

如何使我的模型和控制器都可以访问此方法,但代码只出现一次?这更像是一个 Ruby 问题,而不是一个 Rails 问题,反映了我对 OOP 的新手。我猜模块或混合是答案,但到目前为止我还没有真正使用过其中任何一个,需要一点指导。

Thanks.


模块在 ruby​​ 中用于 3 种不同的用途。首先是命名空间。模块内部的类或常量定义不会与该模块外部的类或常量发生冲突。像这样的东西

class Product
  def foo
    puts 'first'
  end
end

module Affiliate
  class Product
    puts 'second'
  end
end

p = Product.new
p.foo # => 'first'

p = Affiliate::Product.new
p.foo # => 'second'

模块的第二个用途是作为粘贴方法的地方,而这些方法实际上在其他地方没有位置。您也可以在类中执行此操作,但是使用模块会告诉阅读代码的人它并不意味着被实例化。像这样的东西

module Foo
  def self.bar
    puts 'hi'
  end
end

Foo.bar #=> 'hi'

最后(也是最令人困惑的)是模块可以包含到其他类中。以这种方式使用它们也称为混合,因为您将所有方法“混合”到您所包含的任何内容中。

module Foo
  def bar
    puts 'hi'
  end
end

class Baz
  include Foo
end

b = Baz.new
b.bar #=> 'hi'

Mixins 实际上是一个比我在这里介绍的更复杂的主题,但深入探讨可能会令人困惑。

现在,对我来说,S3 似乎真正属于控制器,因为控制器通常是处理传入和传出连接的东西。如果是这种情况,我只会在应用程序控制器上有一个受保护的方法,因为所有其他控制器都可以访问该方法,但仍然是私有的。

如果你确实有充分的理由让它也出现在模型中,我会选择 mixin。就像是

module AwsUtils
private
  def S3
    AWS::S3::Base.establish_connection!\
      :access_key_id     => 'Not telling',
      :secret_access_key => 'Really not telling'

    data = yield
    AWS::S3::Base.disconnect
    data
  end
end

如果你把它放进去lib/aws_utils.rb,您应该能够通过添加来使用它include AwsUtils在您的控制器和模型中。 Rails 知道在 lib 中查找类和模块,但前提是名称匹配(在广泛的情况下)。我将其命名为 AwsUtils,因为我知道 Rails 在看到该内容时会查找什么 (aws_utils.rb),而且说实话,我不知道 S3Utils 需要什么;-)

如果我不清楚某些事情,请随时询问更多信息。模块往往是 Ruby 中令人惊叹的东西之一,但对新手来说却是彻头彻尾的困惑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使一个方法可用于 Rails 中的控制器和模型? 的相关文章

随机推荐

  • iOS 7 UIWebView 304 缓存错误,空白页

    我在具有 UIWebView 的应用程序中发现了一个问题 iOS 7 缓存了空白正文 304 响应 导致用户刷新 UIWebView 时显示空白页面 这不是良好的用户体验 我正在尝试找出如何在 iOS 端解决此问题 因为我无法控制 Amaz
  • unmodifierList 线程安全吗?

    我有一个字符串 tagList 列表 需要在多个线程之间共享以供读取 因此我创建了它的不可修改版本并将其传递给线程 我不确定它是否是线程安全的 因为线程只读取该列表 所以我猜应该可以吧 另外 当我将不可修改的列表传递给线程时 它是传递单个副
  • 将自纪元以来的时间戳转换为 datetime.datetime

    自纪元以来我有以下时间戳 Timestamp 1346114717972 1354087827000 如何将这些时间戳转换为某种特定的输出格式 例如mm dd yyyy hr min sec 我尝试将它们转换为datetime dateti
  • 如何为 RabbitMQ 连接设置自定义名称?

    能够通过连接名称识别 RabbitMQ 客户端将非常有用 我正在使用 Spring Cloud Streams 抽象 并且使用默认设置我得到类似的东西 如何在 Spring Boot 客户端中设置自定义 RabbitMQ 连接名称 EDIT
  • Gridview 中的 TimeSpan DataFormatString

    我有一个带有来自 linq 查询的 ObjectDataSource 的 gridview 源的变量之一是时间跨度 我将绑定字段与 DataField MyTimeSpanVariable 绑定 数据包含以秒和分钟为单位的时间 很少以小时为
  • EF5 收到此错误消息:无法检查模型兼容性,因为数据库不包含模型元数据

    每次运行该应用程序时 都会显示此错误消息 我正在使用实体Framework 5 Code First 这是错误消息 System NotSupportedException Model compatibility cannot be che
  • 分布式 Elixir 示例不起作用

    我有一个非常简单的 Elixir 代码示例 我想在不同的节点上运行 第一个节点位于我的笔记本电脑上 第二个节点是 Raspberry Pi 通过 SSH 访问 代码很简单 node1 my computer defmodule Hello
  • Visual Studio 和 SQL Server - 安装顺序正确吗?

    我正在重建我的开发机器 这个问题对我来说并不新鲜 但我不记得解决方案 我从 SQL 2008 Developer 开始 然后是 VS 2008 Pro SQL SP1 VS SP1 结果是我无法打开SSIS项目 参见下面的错误 正确的顺序是
  • 监听 Flutter 中的 API 变化

    假设我有一个 API 它提供一个返回 id 和名称的 JSON 响应 在移动应用程序中 通常我会发出一个 http GET 响应 以便在与服务器的一次性连接中获取此数据 并在应用程序中显示结果 但是 如果数据随着时间的推移而变化 并且我想在
  • 如何在asp.net中显示Page_Load函数中设置的变量值

    我有一个从数据库获取的变量 我想在 html 之间的 aspx 页面中输出该变量 我试图将其公开 但它显示一些错误 如何在其 aspx 页面中使用页面加载函数中设置的变量 第一种方式 您将 Literal 控件放置在要显示变量的位置 然后在
  • 带有选项的简单选择标签在 Chrome 上不起作用

    我遇到了这个问题 我无法在我的 chrome 上扩展这个简单的选择标签
  • 在应用程序中使用多个网络接口

    我编写了一个应用程序 通过 wifi 触发索尼 qx 智能手机可连接相机 但是 我需要通过另一个本地网络实时传输手机上的图像 由于 wifi 卡用于 qx 连接 我需要能够通过 USB 使用以太网从手机传输图像 HTTP 请求将用于触发相机
  • 当手动将进度设置为 MotionLayout 时,它会清除所有约束

    我有带有两个小部件的 MotionLayout 一个在 MotionLayout 中描述 第二个在场景文件中描述 布局文件
  • 如何获取用户控件数据类型所在的TabPage

    我正在使用用户控件包装器方法构建自定义数据类型 我在其中添加现有的 TinyMCE 数据类型 问题是我需要找到一种方法来动态获取数据类型所在的当前 TabPage 以便我可以将 TinyMCE 按钮添加到菜单中 这就是我目前所拥有的 Tab
  • 使用 Ajax 和 PHP $_FILES 从 Canvas 元素发送图像

    我需要能够将图像和一些表单字段从客户端画布元素发送到 PHP 脚本 最终以 POST 和 FILES 结束 当我这样发送时
  • 将 Haskell 线程与内核线程进行比较 - 我的基准测试可行吗?

    这实际上是我的大学项目 在我的文章中 我需要提供证据证明 Haskell 线程的创建速度比普通内核线程更快 我知道最好参考一些研究论文 但重点是我必须自己进行基准测试 这是我的想法 我用 C 使用 pthreads 和 Haskell 编写
  • 错误“HttpServletRequest 引用了缺失的 String 类型”

    我正在 struts 中实现一个项目 其中 JSP 页面出现错误 我已经在 Eclipse IDE 中配置了 Tomcat 6 JRE 和 JDK 6 代码是 request getContextPath 错误是 The method ge
  • PHP 依赖注入

    我正在尝试了解依赖注入 并且在很大程度上我理解它 然而 如果由于某种原因 我的一个类依赖于多个类 而不是将所有这些都传递给构造函数中的这个类 是否有更好 更明智的方法 我听说过 DI 容器 这是我解决这个问题的方法吗 我应该从哪里开始使用这
  • 使用 PHPExcel 读取包含合并单元格的 Excel 工作表

    我想完整地阅读 Excel 工作表并使用 AJAX 将每一行发送到另一个页面进行处理 因此 我使用以下代码将 Excel 工作表数据转换为 JSON 数组 参考库中提供的 PHPExcel 示例
  • 如何使一个方法可用于 Rails 中的控制器和模型?

    我的 Rails 应用程序中有一个私有方法来连接到 Amazon S3 执行传递的代码块 然后关闭与 S3 的连接 看起来是这样 def S3 AWS S3 Base establish connection access key id g