bra*_*rad 10 ruby oop ruby-on-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
Run Code Online (Sandbox Code Playgroud)
它被称为这样(作为一个例子);
send_data(S3 {AWS::S3::S3Object.value("#{@upload_file.name}",'bucket')}, :filename => @upload_file.name)
Run Code Online (Sandbox Code Playgroud)
我在我的控制器和模型中以多种方式调用此方法,因此将它作为私有方法包含在两个类中.这很好用,我很高兴,但它不是很干.
如何让我的模型和控制器都可以访问此方法,但只能让代码出现一次?这是一个Ruby问题而不是Rails问题,反映了我对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'
Run Code Online (Sandbox Code Playgroud)
模块的第二个用途是作为一个固定方法的地方,这些方法在其他任何地方都没有.您也可以在类中执行此操作,但使用模块类型可以告诉读取代码的人员,这些代码并不是要实现的.像这样的东西
module Foo
def self.bar
puts 'hi'
end
end
Foo.bar #=> 'hi'
Run Code Online (Sandbox Code Playgroud)
最后(也是最令人困惑的)是模块可以包含在其他类中.以这种方式使用它们也被称为mixin,因为您将所有方法"混合"到您所包含的任何内容中.
module Foo
def bar
puts 'hi'
end
end
class Baz
include Foo
end
b = Baz.new
b.bar #=> 'hi'
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
如果你把它放进去lib/aws_utils.rb
,你应该可以通过添加include AwsUtils
你的控制器和你的模型来使用它.Rails知道在lib中查找类和模块,但只有在名称匹配时(大例).我把它称为AwsUtils,因为我知道当它看到(aws_utils.rb)时会看到什么轨道,说实话,我不知道S3Utils需要什么;-)
如果我不清楚某些事情,请随时询问更多信息.模块往往是红宝石中的那些东西之一,虽然令人惊讶,但对新手来说却是令人费解的.
归档时间: |
|
查看次数: |
2586 次 |
最近记录: |