Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.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 当链接方法时,子方法可以访问和使用';家长';方法?(即对象、父对象、子对象)_Ruby On Rails_Ruby_Method Chaining - Fatal编程技术网

Ruby on rails 当链接方法时,子方法可以访问和使用';家长';方法?(即对象、父对象、子对象)

Ruby on rails 当链接方法时,子方法可以访问和使用';家长';方法?(即对象、父对象、子对象),ruby-on-rails,ruby,method-chaining,Ruby On Rails,Ruby,Method Chaining,说明 我创建了一个Report对象,该对象具有不同的环境/组(:live&:demo),它们只是数组,将填充ReportItem对象,这些对象具有以下属性:currency、:gross、:net(以及gross&net hold Ruby Money对象) 在Report.rb类中,有两个方法称为add\u money\u to\u net和add\u money\u to\u gross都有一个变量,我临时命名为@group 问题 (report=report.new) 我试图做的是链式方法

说明 我创建了一个
Report
对象,该对象具有不同的环境/组(:live&:demo),它们只是数组,将填充
ReportItem
对象,这些对象具有以下属性
:currency、:gross、:net
(以及gross&net hold Ruby Money对象)

Report.rb
类中,有两个方法称为
add\u money\u to\u net
add\u money\u to\u gross
都有一个变量,我临时命名为
@group

问题
report=report.new
) 我试图做的是链式方法,如
report.demo.add\u money\u to\u gross()
如果调用此方法,我希望能够访问
report.demo
(代替我的
@group
变量)。或者调用
report.live.add_money\u to_gross()
应该允许我访问
report.live
。这可能吗

我希望这是有道理的。如果有什么不清楚的地方,请告诉我

报告.rb

课堂报告
包括ActiveModel::Model
属性访问器:演示,:实时
def初始化
@演示=[]
@现场=[]
结束
def演示
@演示
自己
结束
def现场直播
@生活
自己
结束
def将_money_添加到_net(money)
添加钱(组:@group,钱:钱)
结束
def将_money_添加到_gross(money)中
添加钱(组:@group,钱:钱)
结束
私有的
def添加资金(组:,资金:)
item=group.find{s|s.currency==money.currency}
如果项
item.net+=货币
其他的

组我了解您想要做的事情,几乎就像命令行管道操作一样。而且,不,你的方法不可能(或者,依我看,推荐)

考虑演示方法:

def demo
  @demo
  self
end
这一行
@demo
实际上是一个禁止操作的命令。这里没有“返回”任何内容,没有分配任何内容,只是。。。那里这里唯一返回的是self

现在,您可以执行以下操作:

def demo
  @group = @demo
  self
end
那就打电话吧

report.live.add_money_to_gross(money)
现在它应该按照你的意愿工作。在这里,
live
demo
更像是状态管理器,在调用操作方法之前设置
@group
的状态

这就是说,这有点脆弱,需要按特定顺序调用,而这个临时变量似乎是一个等待发生的陷阱。为什么?因为称之为:

report.add_money_to_gross(money)
是一个有效的调用,但除非先调用了
live
demo
。不会抛出任何错误,它只会添加到最后设置的
@group

相反,对我来说,创建一个新对象来封装所有这些内容更有意义:

class ReportItemArray < Array
  def add_money_to_net money
    item = find_item(money)
    if item
      item.net += money
    else
      self << ReportItem.new(currency: money.currency.to_s, net: money)
    end
  end
  def add_money_to_gross money
    item = find_item(money)
    if item
      item.gross += money
    else
      self << ReportItem.new(currency: money.currency.to_s, gross: money)
    end
  end
  def find_item money
    self.find {|s| s.currency == money.currency }
  end
end
请注意,这两种方法
live
demo
现在实际上已经过时,因为您使用的是
attr\u accessor
,它们不再返回任何特殊的内容,因此您实际上不需要重写它们,只需显式地重写即可。
live
demo
对象本身仍然是数组,因此应该与代码的其余部分兼容,但是
add\u money
方法也附加到这些数组对象,因此现在您可以执行以下操作:

report.live.add_money_to_gross(money)
现在通过调用
live
,您就得到了数组,由于这些方法是该数组对象的一部分,您不再需要传递上下文,它们本身就知道它(
group
变成
self
)。因此,调用该方法将作用于给定的数组

这样做可以消除调用
报告的可能性。将\u money\u添加到\u gross
(如果这样做,将引发错误),这很好,因为此处的调用需要更多上下文(组)才能完成。这也消除了操作顺序冲突,因为不再需要状态

最后一个不相关的注意事项,您可能已经捕获了我对上述问题的修复,但是您的
add\u money
方法始终会添加到
ReportItem
net
,即使原始调用是从
add\u money\u to\u gross
发出的

report.live.add_money_to_gross(money)