如何使(Ruby)DataMapper自定义类型工作?

nos*_*dog 2 ruby datamapper

我有一个SchoolDay代表上学日的课程:它可以告诉你日期,学期,学期,周和日.它可以生成像"Sem1 13A Fri"这样的字符串.要将这些对象存储在数据库中,我希望将它们序列化为字符串.

这是我的DataMapper自定义类型代码.我有点从dm-types中的代码中剔除了想法,因为(令人失望的是)没有用于创建自定义类型的真实文档.对不起,很久了.

module DataMapper
  class Property
    class SchoolDay < DataMapper::Property::String

      #load_as ::SchoolRecord::DomainObjects::SchoolDay
      # Commented out: the 'load_as' method is not found

      def load(value)
        # Take a string from the database and load it. We need a calendar!
        val = case value
        when ::String then calendar.schoolday(value)
        when ::SR::DO::SchoolDay then value
        else
          # fail
        end
      end

      def dump(value)
        # Store a SchoolDay value into the database as a string.
        case value
        when SR::DO::SchoolDay
          sd = value
          "Sem#{sd.semester} #{sd.weekstr} #{sd.day}"
        when ::String
          value
        else
          # fail
        end
      end

      def typecast(value)
        # I don't know what this is supposed to do -- that is, when and why it
        # is called -- but I am aping the behaviour of the Regexp custom type,
        # which, like this one, stores as a String and loads as something else.
        load(value)
      end

      # private methods calendar() and error_message() omitted
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

此代码适用于从(SQLite)数据库读取,但不适用于创建新行.错误消息是:

Schoolday must be of type String
Run Code Online (Sandbox Code Playgroud)

定义DataMapper资源并尝试创建记录的代码是:

class LessonDescription
  include DataMapper::Resource
  property :id,          Serial
  property :schoolday,   SchoolDay  # "Sem1 3A Fri"
  property :class_label, String     # "10"
  property :period,      Integer    # (0..6), 0 being before school
  property :description, Text       # "Completed yesterday's worksheet. hw:(4-07)"
end

# ...

ld = LessonDescription.create(
  schoolday:    @schoolday,
  class_label:  @class_label,
  period:       @period,
  description:  description
)
Run Code Online (Sandbox Code Playgroud)

以下是dm-types库中Regexp datamapper类型的代码.这很简单!

module DataMapper
  class Property
    class Regexp < String
      load_as ::Regexp                          # NOTE THIS LINE

      def load(value)
        ::Regexp.new(value) unless value.nil?
      end

      def dump(value)
        value.source unless value.nil?
      end

      def typecast(value)
        load(value)
      end

    end
  end
end
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我不能load_as在我的代码中使用该行.

总结一下:我正在尝试创建一个在SchoolDay(域对象)和String(数据库表示)之间进行转换的自定义类型.翻译很简单,我已经主要从DataMapper Regexp类型复制了代码结构.但是当我试图保存一个SchoolDay时,它抱怨我没有给它一个字符串.令人沮丧的是,我不能使用内置和自定义类型使用的"load_as"方法,即使我有最新的gem.我找不到在DataMapper的源代码中定义的"load_as"方法.但它被称为!

抱歉这个荒谬的长度.任何帮助将非常感激,因为指向创建这些我不知何故错过的东西的指南.

Adi*_*ann 9

似乎github上当前的dm-types代码还没有进入任何正式版本 - 这就是为什么load_as在你的例子中不起作用的原因.但是尝试添加此方法:

module DataMapper
  class Property
    class SchoolDay < DataMapper::Property::String

      def custom?
        true
      end

    end
  end
end
Run Code Online (Sandbox Code Playgroud)

那是在这里工作.

  • 别客气.请不要忘记将答案标记为正确;) (3认同)