【问题标题】:has n of Strings in DataMapper在 DataMapper 中有 n 个字符串
【发布时间】:2012-12-08 09:40:35
【问题描述】:

我正在为 Web 服务编写客户端,其模型的一部分是属于用户的字符串列表,其中包含用户之前使用的用户名。我正在尝试将 DataMapper 用于我的客户端 gem,我的第一个想法是使用 DataMapper 的 has n 语法,但我似乎无法将其应用于字符串。有没有更好的方法呢?

我当前的代码:

class User
  include DataMapper::Resource

  # Some Properties here

  has n, :also_known_as, 'String'
end

这产生的错误是这样的:

irb(main):001:0> require 'cloudsdale'
NoMethodError: undefined method `relationships' for String:Class
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/associations/one_to_many.rb:109:in `finalize'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/model.rb:782:in `block in finalize_relationships'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/subject_set.rb:210:in `block in each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `block in each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/subject_set.rb:210:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/model.rb:782:in `finalize_relationships'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/model.rb:137:in `finalize'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core.rb:281:in `block in finalize'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/descendant_set.rb:64:in `block in each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/subject_set.rb:210:in `block in each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `block in each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/ordered_set.rb:319:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/subject_set.rb:210:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core/support/descendant_set.rb:63:in `each'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/dm-core-1.2.0/lib/dm-core.rb:281:in `finalize'
    from C:/Ruby193/lib/ruby/gems/1.9.1/gems/cloudsdale-0.0.1/lib/cloudsdale.rb:19:in `<top (required)>'
    from C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `require'
    from C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `rescue in require'
    from C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
    from (irb):1
    from C:/Ruby193/bin/irb:12:in `<main>'irb(main):002:0>

产生错误的文件是这样的:

# Load in DataMapper
# Change the setup to meet your DB needs
require 'data_mapper'
DataMapper.setup(:default, 'abstract::')

# API objects
require 'cloudsdale/version'
require 'cloudsdale/api/api'
require 'cloudsdale/client'

# Models
require 'cloudsdale/models/user'
require 'cloudsdale/models/cloud'
require 'cloudsdale/models/avatar'
require 'cloudsdale/models/ban'
require 'cloudsdale/models/chat'

# Finalize DataMapper so the models Load
DataMapper.finalize

【问题讨论】:

    标签: ruby gem datamapper


    【解决方案1】:

    你为什么在这里使用'String'

    has n, :also_known_as, 'String'
    

    没有意义,删除它:

    has n, :also_known_as
    

    如果要设置模型,请使用:model 选项:

    has n, :also_known_as, :model => ModelName
    

    我不确定你想使用String 作为模型名称。

    您很可能需要一个额外的模型来保留用户以前的名字:

    class UserAlias
      include DataMapper::Resource
    
      # ...
    end
    
    
    class User
      include DataMapper::Resource
    
      # ...
    
      has n, :also_known_as, :model => UserAlias
    end
    

    【讨论】:

    • 我的目标是简单地将平台字符串模型用于列表。从我的角度来看,当我存储的只是一个字符串列表时,使用完全独立的模型似乎有点过头了,因此我试图让 DataMapper 将列表映射到 String 类。
    • 您只能与DataMapper::Resource 类建立数据库关系。
    【解决方案2】:

    如果您希望能够通过 datamapper 1.x 查询 DSL 搜索旧用户名,您需要定义一个额外的模型。

    class User
      include DataMapper::Resource
    
      # ...
    
      has n, :also_known_as, :model => UserNameHistory
    end
    
    class UsernameHistory
      include DataMapper::Resource
      property :id, Serial
      property :name
      belongs_to :user
    end
    

    如果您不需要通过旧用户名进行查询,您可以使用序列化的大对象。作为建议,您可以像这样使用来自dm-typesDataMapper::Property::YAML

    class User
      include DataMapper::Resource
    
      # ...
    
      property :also_known_as, YAML
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      相关资源
      最近更新 更多