2010-09-20 30 views
0

我有一个骷髅级:红宝石如何定义作家法“<<”

class Foo 
    def bar 
    # returns some sort of array 
    end 
end 

,但一个人如何能在“作家”的方法添加到“酒吧”,以便使阵列#推行为?

Foo.new.bar<<['Smile'] 
_.bar #=> ['Smile'] 

编辑: 我应该进一步扩展我的问题。 有两个类。 Foo和Bar,非常像ActiveRecord has_many关系,其中Foo has_many酒吧

但是我实际上将Bar的ID存储在Foo的一个方法中。我的名字是方法bar_ids

所以@foo = Foo.new(:bar_ids => [1,2,3])

正如你可以想像,如果我想查什么酒吧属于@ FOO,我必须真正做类似Bar.where(:ID => @ foo.bar_ids)

所以我决定让刚刚入选酒吧做到这一点 类Foo #另一种方法... 高清bar Bar.where(:id => bar_ids) end end

解决了。现在我可以做@ foo.bar#=>所有属于@foo的酒吧

现在我也想拥有像ActiveRecord关联那种推式方法,只是为了在关联另一个酒吧时删除“id”键入反对Foo对象

目前,这个工程: @ foo.bar_ids < < Bar.new.id @ foo.save

但我想: @ foo.bar < < Bar.new#其中新酒吧的ID将被推入@foo的bar_ids方法 @ foo.save

感谢您的全力帮助,我非常感谢您对此的看法!

+0

什么是你究竟从杆法期待?它应该只作为一个Array对象的getter? – David 2010-09-20 14:14:37

+0

@大卫,这是完全正确的。我想要实现的就像ActiveRecord has_many关系,你可以做@ project.line_items << LineItem.create(...) – 2010-09-20 14:20:12

+0

@Nik,'@project.line_items << ...'返回一个'Array',而不是'@ project'。 'Foo.new.bar'不可能返回一个可以同时调用''''和'Foo'对象的数组! – 2010-09-20 14:28:19

回答

2
class Foo 
    attr_reader :bar 
    def initialize 
    @bar = Array.new 
    def @bar.<< arg 
     self.push arg.id 
    end 
    end 

end 

class Bar 
    attr_accessor :id 
    def initialize id 
    self.id = id 
    end 
end 


f = Foo.new 
bars = (1..5).map{|i| Bar.new i} 

f.bar << bars[2] 
f.bar << bars[4] 

p f.bar #=> [3, 5] 
+0

@Ormuriauga。这看起来很酷,你是否会友好地解释为什么def @bar。<< arg是否在初始化? – 2010-09-20 15:12:03

+1

@Nik,是ormuriauga的解决方案非常酷。 'def @bar。<<'在'Foo'的'initialize'方法中,因为他在那里定制了'@ bar'('Array')对象(通过用单例方法覆盖普通的数组''''方法)。 – horseyguy 2010-09-20 18:30:10

+0

@Ormuriauga&@Banister谢谢你。 – 2010-09-20 20:43:27

1

返回已定义方法<<的对象。

+0

因此,根据我的例子,bar/does /返回一个数组,它具有<<定义,所以我完成了? – 2010-09-20 14:13:52

+0

如果你总是返回相同的数组对象,那么你就完成了。否则,'_.bar#=> ['Smile']'不起作用 – David 2010-09-20 14:18:52

0

除非我误解了你的想法,为什么不把bar方法作为内部数组成员的getter?

class Foo 
    attr_reader :bar 

    def initialize 
    @bar = [] 
    end 
end 

f = Foo.new 
f.bar << 'abc' 
# f.bar => ['abc']