有没有办法覆盖<< Ruby中的运算符?

时间:2012-03-02 16:31:28

标签: ruby-on-rails ruby override

我正在尝试做类似的事情:

account.users << User.new

但我需要用户成为帐户的一种方法。所以我尝试过这样的事情:

def users<<(obj)

但我没有运气。这甚至可以用Ruby做吗?我认为是因为ActiveRecord关系似乎在Rails中以这种方式工作。

6 个答案:

答案 0 :(得分:9)

检查此答案:Rails: Overriding ActiveRecord association method

[此代码完全来自其他答案,此处为未来的搜索者]

has_many :tags, :through => :taggings, :order => :name do
    def << (value)
      "overriden" #your code here
    end     
  end

答案 1 :(得分:5)

似乎您可能没有描述您的实际问题,但回答您的问题 - 是的,您可以覆盖<<运算符:

class Foo
  def <<(x)
    puts "hi! #{x}"
  end
end

f = Foo.new
=> #<Foo:0x00000009b389f0>
> f << "there"
hi! there

答案 2 :(得分:2)

我假设您有这样的模型:

class Account < ActiveRecord::Base
  has_and_belongs_to_many :users
end

要覆盖Account#users<<,您需要在传递给has_and_belongs_to_many的块中定义它:

class Account < ActiveRecord::Base
  has_and_belongs_to_many :users do
    def <<(user)
      # ...
    end
  end
end

您可以参考Account

访问相应的proxy_association.owner对象
def <<(user)
  account = proxy_association.owner
end

要拨打原始Account#users<<,请致电Account#users.concat

def <<(user)
  account = proxy_association.owner
  # user = do_something(user)
  account.users.concat(user)
end

有关详情,请参阅此页:Association extensions - ActiveRecord

答案 3 :(得分:1)

在这种情况下,它是您用户的<<类。可以是ArrayAssociationProxy

最简单的方法是创建一个新方法来做你想做的事。

您可以改为按实例覆盖该方法。

account.users.instance_eval do
  def <<(x)
    put 'add'
  end
end

account.users << User.new
# add

但是你需要在添加&lt;&lt;

之前一直这样做

答案 4 :(得分:0)

users会返回一个已覆盖<<运算符的对象,例如ArrayIOString或您创建的任何类型。你覆盖如下:

class SomeType
  def <<(obj)
    puts "Appending #{obj}"
  end
end

答案 5 :(得分:0)

如果您在向User集合中添加users时尝试执行操作,则可以使用association callbacks代替覆盖<<(因为有class Account has_many :users, :after_add => :on_user_add def on_user_add(user) p "Added user : #{user.name} to the account: #{name}" end end 将对象添加到关联的许多方法。)

{{1}}