ruby-on-rails – 如何在Rails中为我的控制器和模型提供方法?

我的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)

我在控制器和模型中以多种方式调用方法,因此将其作为私有方法包含在这两个类中.这工作正常,我很高兴,但它不是很干.

我如何使这种方法可以访问我的模型和控制器,但只有代码出现一次?这更像是Rails问题的Ruby问题,反映了我对OOP的新意.我猜测一个模块或混合是答案,但是直到现在还没有真正使用这些模块,需要一些手持.

谢谢.

解决方法

模块用于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似乎是一个真正属于控制器的东西,因为控制器通常是处理传入和传出连接的事情.如果是这种情况,我将在应用程序控制器上拥有一个受保护的方法,因为所有其他控制器都可以访问,但仍然是私有的.

如果你有一个很好的理由在模特儿,我会去混合.就像是

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中的一个,虽然惊人,但对新手来说,是彻头彻尾的困惑.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...