Создание класса и динамическое добавление методов в Ruby - PullRequest
0 голосов
/ 06 марта 2012

Как мне создать новый класс и добавить к нему несколько методов, не прибегая к "eval"?

Вот что я пытаюсь сделать;Я хотел бы преобразовать эту структуру:

obj = [
{
    :scope => 'account',
    :fields => [
        { :title => 'title', :length => 64, :required => true   },
        { :title => 'email', :length => 256, :required => true, :type => 'email'    }
    ],
    :before_save => Proc.new{
        #do something here
    },
},

{
    :scope => 'product',
    :fields => [
        { :title => 'title', :length => 64, :required => true   },
        { :title => 'description', :length => 256, :required => true    },
        { :title => 'cost', :required => true, :type => 'decimal'   }
    ]
    },
]

в эту:

class Account
    include DataMapper::Resource

    property :id,       Serial
    property :title,    String, :length => 64, :required => true
    property :email,    String, :length => 256, :required => true

    def before_save
        #do something here
    end
end

...

Спасибо!

Ответы [ 2 ]

2 голосов
/ 06 марта 2012

Как уже говорил Эндрю, существуют разные способы динамического создания класса.Это может быть один из них:

Допустим, вы начинаете с одной модели DM (не использовали DM, беря первую из документов):

class Post
  include DataMapper::Resource

  property :id,         Serial    # An auto-increment integer key
  property :title,      String    # A varchar type string, for short strings
  property :body,       Text      # A text block, for longer string data.
  property :created_at, DateTime  # A DateTime, for any date you might like.
end

, и вы хотите создатьэто динамически, из метаданных, данных в хэше вида

{:ClassName => {:field1 => :Type1, :field2 => :Type2 ...}}

Вы можете сделать:

require 'data_mapper'

models = {:Post => {
  :id => :Serial,
  :title => :String,
  :body => :Text
}}

models.each do |name, fields|
  klass = Class.new do
    include DataMapper::Resource

    fields.each do |field_name, field_type|
      property(field_name, const_get(field_type))
    end
  end
  Object.const_set(name, klass)
end

Ключевые методы:

0 голосов
/ 06 марта 2012

Если вы хотите взглянуть на реальный пример, обратитесь к коду в этой библиотеке: https://github.com/apohllo/rod/blob/v0.7.x/lib/rod/model.rb#L410

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...