2012-03-02 32 views
8

Tôi đang cố gắng làm điều gì đó như:Có cách nào để ghi đè toán tử << trong Ruby không?

account.users << User.new 

Nhưng tôi cần người dùng làm phương thức trên tài khoản. Vì vậy, tôi đã thử những thứ như:

def users<<(obj) 

Nhưng tôi đã không có may mắn với điều đó. Điều này thậm chí có thể làm trong Ruby? Tôi sẽ giả định như vậy bởi vì các mối quan hệ ActiveRecord dường như làm việc theo cách này trong Rails.

+0

là hiệp hội 'Rails users' này? – lulalala

Trả lời

1

Trong trường hợp này là << của lớp bạn của bạn Người dùng. Vì vậy, có thể là Array hoặc AssociationProxy.

Cách đơn giản nhất là tạo phương thức mới để thực hiện những gì bạn muốn.

Thay vào đó, bạn có thể ghi đè phương thức.

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

account.users << User.new 
# add 

Nhưng bạn cần làm điều đó tất cả các thời gian trước khi bạn thêm bởi < <

0

users sẽ trả về một đối tượng mà đã ghi đè << điều hành như Array, IO, String, hoặc bất kỳ loại bạn tạo ra. Bạn ghi đè như thế này:

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

Nó có vẻ như bạn có thể không được mô tả vấn đề thực tế của bạn, nhưng để trả lời câu hỏi của bạn - có bạn có thể ghi đè lên << điều hành:

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

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

Tôi không muốn sử dụng lớp Foo. Tôi muốn người dùng foo.users << x –

+0

@JohnBaker, 'foo.users << obj' tương đương với' foo.users.send: <<, obj'. Bạn chỉ cần trả về mảng người dùng của Foo; phương thức ['Array # <<'] (http://ruby-doc.org/core-1.9.3/Array.html#method-i-3C-3C) sẽ đẩy thêm người dùng vào mảng. –

8

Kiểm tra câu trả lời này: Rails: Overriding ActiveRecord association method

[mã này là hoàn toàn từ các câu trả lời khác, vào đây để tìm kiếm tương lai]

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

Nếu bạn đang cố thực hiện hành động khi thêm User vào bộ sưu tập users, bạn có thể sử dụng association callbacks thay vì vượt quá << (vì có nhiều cách để thêm đối tượng vào liên kết).

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

Tôi giả sử bạn có một mô hình như thế này:

class Account < ActiveRecord::Base 
    has_and_belongs_to_many :users 
end 

Để ghi đè Account#users<<, bạn cần phải định nghĩa nó trong một khối mà bạn vượt qua để has_and_belongs_to_many:

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

Bạn có thể truy cập đối tượng Account thích hợp bằng cách tham chiếu đến proxy_association.owner:

def <<(user) 
    account = proxy_association.owner 
end 

Để gọi bản gốc Account#users<<, gọi Account#users.concat:

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

Để biết thêm chi tiết, xem trang này: Association extensions - ActiveRecord

Các vấn đề liên quan