【问题标题】:Rails3 and DatamapperRails3 和数据映射器
【发布时间】:2011-03-17 11:44:10
【问题描述】:

我将从使用 AR 和 arel 的 rails 3 应用程序迁移到 datamapper。我喜欢像 Person.where(...).where(...).somescope.paginate(...).order(...) 这样的范围链。如何从这种 arel 方法迁移到 datamapper。

【问题讨论】:

    标签: ruby ruby-on-rails-3 activerecord migration datamapper


    【解决方案1】:

    DataMapper 中的命名范围只是您在模型类上定义的类方法。在这些类方法中,您通常会调用 #all 并附带一些条件来取回 DataMapper::Collection。为了使您的类方法可链接,您必须确保返回DataMapper::Collection

    为了完整起见,这里是安装说明...

    gem install dm-core
    gem install dm-migrations
    gem install dm-sqlite-adapter
    gem install dm-chunked_query
    

    以及让您开始的代码(将其放入 test.rb 以获得最大的可重复性)

    require 'rubygems'
    require 'dm-core'
    require 'dm-migrations'
    require 'dm-chunked_query'
    
    class Person
      include DataMapper::Resource
    
      property :id,        Serial
      property :name,      String
      property :hobby,     String
      property :country,   String
      property :continent, String
    
      def self.european
        all(:continent => 'Europe')
      end
    
      def self.hackers
        all(:hobby => 'Hacking')
      end
    
      def self.named(name)
        all(:name => name)
      end
    end
    
    DataMapper::Logger.new($stdout, :debug)
    DataMapper.setup(:default, 'sqlite::memory:')
    
    DataMapper.finalize.auto_migrate!
    
    1.upto(10) do |i|
      Person.create(:name => "Alex", :hobby => 'Hacking', :country => "Country-#{i}", :continent => 'Europe')
    end
    
    # you could even skip the explicit call to #all
    # i just left it in there because it reads nicely
    Person.all.european.hackers.named('Alex').chunks(5).each_with_index do |chunk, idx|
      puts "Rendering page #{idx + 1}"
      chunk.each do |person|
        puts "Someone named #{person.name} who lives in #{person.country}"
      end
    end
    
    __END__
    
    ruby-1.9.2-p180@datamapper mungo:dm-rails snusnu$ ruby test.rb
     ~ (0.000102) SELECT sqlite_version(*)
     ~ (0.000132) DROP TABLE IF EXISTS "people"
     ~ (0.000013) PRAGMA table_info("people")
     ~ (0.000315) CREATE TABLE "people" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "name" VARCHAR(50), "hobby" VARCHAR(50), "country" VARCHAR(50), "continent" VARCHAR(50))
     ~ (0.000049) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-1', 'Europe')
     ~ (0.000056) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-2', 'Europe')
     ~ (0.000044) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-3', 'Europe')
     ~ (0.000043) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-4', 'Europe')
     ~ (0.000037) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-5', 'Europe')
     ~ (0.000038) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-6', 'Europe')
     ~ (0.000035) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-7', 'Europe')
     ~ (0.000035) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-8', 'Europe')
     ~ (0.000036) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-9', 'Europe')
     ~ (0.000039) INSERT INTO "people" ("name", "hobby", "country", "continent") VALUES ('Alex', 'Hacking', 'Country-10', 'Europe')
     ~ (0.000069) SELECT "id", "name", "hobby", "country", "continent" FROM "people" WHERE ("continent" = 'Europe' AND "hobby" = 'Hacking' AND "name" = 'Alex') ORDER BY "id"
    Rendering page 1
    Someone named Alex who lives in Country-1
    Someone named Alex who lives in Country-2
    Someone named Alex who lives in Country-3
    Someone named Alex who lives in Country-4
    Someone named Alex who lives in Country-5
    Rendering page 2
    Someone named Alex who lives in Country-6
    Someone named Alex who lives in Country-7
    Someone named Alex who lives in Country-8
    Someone named Alex who lives in Country-9
    Someone named Alex who lives in Country-10
    

    请参阅https://github.com/postmodern/dm-chunked_query,了解有关提供此示例中使用的#chunks 方法的低级分页(批处理)方法的更多信息。

    【讨论】:

    • tnx,这将很有用。一般来说,DataMapper 中的 all = AR 中的 where + metawhere?
    • 抱歉,我不熟悉 metawhere,也不太熟悉新的基于 arel 的 AR。一般来说,DataMapper::Model.all 是使用 DM 构建查询的 API,一旦“被踢”,最终会导致数据的物化集合。一旦您掌握了DataMapper::QueryDataMapper::Collection 的句柄,您就可以进一步细化它以构建最终查询或将获取的数据转换为适合(进一步)处理的形式。
    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2011-10-01
    • 2013-11-07
    • 2013-09-08
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多