2014-09-22 35 views
2

我想寫類方法my_method(如驗證),使用代碼塊。Rails關心:類方法與塊

模型包含下面的代碼:

class Model < ActiveRecord::Base 
    include Usable 
    my_method :arg_1, :arg_2 

    my_method do |model| 
    # just for example 
    if model.attribute.present? 
     :arg3 
    else 
     :arg4 
    end 
    end 
    #... 
end 

my_method在關注定義類方法:

module Usable 
    extend ActiveSupport::Concern 

    # instance methods 
    def instance_method 
    self.class.display_attrs 
    end 
    # ... 

    module ClassMethods 
    # class methods 
    def display_attrs 
     @attrs_for_display ||= [] 
    end 

    def my_method(*attr_names, &block) 
     attr_names.each do |attr| 
     attr_data = { attr: attr } 
     display_attrs << attr_data 
     end 

     display_attrs << { attr: block} if block_given? 
    end 
    end 
end 

實例方法@ model.instance_method正常工作時的論點my_method直接my_method :arg_1, :arg_2推杆

> Model.last.instance_method 
=> [{:attr=>:arg_1}, {:attr=>:arg_2}] 

instance_method時my_method返回一個Proc對象使用塊my_method {:arg_3}

> Model.last.instance_method 
=>[{:attr=> #<Proc:0x00 ... >}] 

如何把在my_method論點實例狀態的根據?例如,@model.instance_method應返回:arg_3如果model.attribute.present?

回答

1

該問題已通過call method解決。 我重寫了instance_method,如下所示:

def instance_method 
    class_attrs = self.class.display_attrs.map { |n| n[:attr] } 
    class_blocks = self.class.display_attrs.map { |n| n[:block].call(self) if n[:block] } 
    (class_attrs + class_blocks).compact! 
    end 

    module ClassMethods 
    #... 
     display_attrs << { block: block} if block_given? 
    #... 
    end