使用'<<&#;用rails模型方法

时间:2014-04-30 11:39:48

标签: ruby-on-rails

我有一个字母,其中包含预定的收件人。这些收件人是个人群组

为了填充个人和群体:

ind = Individual.new
template.individuals << ind

group = Group.new
template.groups << group

是否可以使用名为&#39;收件人&#39;并使用铲子操作员:

template.recipients << (either group or individual)

然后实现该方法,使其将收件人放置在正确的集合中,即如果收件人是一个组,则应将其放入self.groups中,如果收件人是个人,则应将其放在self.individuals中!

请注意,我的设计禁止我从单个基类继承这些类,并且只允许一个容器来保存这两个类。

2 个答案:

答案 0 :(得分:6)

是的,这是可能的。以下是使用代理对象使用铲运算符接收收件人的示例。

class Letter               # (or Template???)
  has_many :individuals
  has_many :groups

  class RecipientsProxy
    def initialize(letter)
      @letter = letter
    end

    def <<(recipient)
      case recipient
      when Individual then @letter.individuals << recipient
      when Group      then @letter.groups << recipient
      end
    end
  end

  def recipients
    @recipients_proxy ||= RecipientsProxy.new(self)
  end
end

letter = Letter.new
letter.recipients << Individual.new
letter.recipients << Group.new
letter.recipients << Individual.new
letter.recipients << Group.new

但也许有更好的解决方案。也许你可以创建一个收件人模型,作为Letter和Individual / Group之间的连接。

class Letter
  has_many :recipients
end

class Recipient
  belongs_to :letter

  belongs_to :individual
  belongs_to :group
end

跟进

您可以使用method_missing将RecipientsProxy对象转发方法调用到当前Letter的所有个人和组的集合。

# RecipientsProxy
def method_missing(method_name, *args, &block)
  recipients = (@letter.individuals + @letter.groups)  # This will create an Array with all Individuals and Groups
  recipients.__send__(method_name, *args, &block)
end


letter.recipients.to_a
letter.recipients.each { |recipient| puts recipient.inspect }

答案 1 :(得分:1)

我没有看到使用template.recipients << item语法实现此目的的任何简单解决方案,但您可以添加一个方法add_recipient,将给定对象分派到正确的集合:

class Letter

  # ...

  def add_recipient(recipient)
    case recipient
      when Individual then self.individuals << recipient
      when Group      then self.groups << recipient
      # else raise "Invalid parameter: #{recipient}"
    end          
  end
end