JRuby 脚本中使用 active record 的问题

heliang7 · 2014年02月17日 · 最后由 heliang7 回复于 2014年02月20日 · 8812 次阅读

代码如下

require 'active_record'
#require 'activerecord-jdbc-adapter'
require 'activerecord-jdbcmssql-adapter'
require 'logger'
require 'D:\\lib\\jdbc-dirver\\mssql\\sqljdbc.jar'

ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(
  adapter:  'sqlserver',
  host:     'localhost',
  username: 'sa',
  password: 'sa',
  database: 'DB'
)

class FormDefine < ActiveRecord::Base
    self.table_name = 'FormDefineTab'
    self.primary_key = 'id'
end

p FormDefine.first(20).to_a

总是最后一行出问题,但是通过 STDOUT 的 logger 可以看到 sql 语句已经执行了(或者生成) 错误如下:

NoMethodError: undefined method `attribute_method_matcher' for 0:Fixnum
                 __send__ at org/jruby/RubyBasicObject.java:1709
                     send at org/jruby/RubyKernel.java:2213
  match_attribute_method? at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activemodel-3.2.13/lib/active_model/attribute_methods.rb:444
              respond_to? at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activemodel-3.2.13/lib/active_model/attribute_methods.rb:431
              respond_to? at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:169
           __run_callback at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:398
      _run_find_callbacks at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:390
                 __send__ at org/jruby/RubyBasicObject.java:1703
                     send at org/jruby/RubyKernel.java:2209
            run_callbacks at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81
                init_with at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/base.rb:523
              instantiate at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/inheritance.rb:68
              find_by_sql at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/querying.rb:38
                 collect! at org/jruby/RubyArray.java:2441
              find_by_sql at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/querying.rb:38
       logging_query_plan at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/explain.rb:41
              find_by_sql at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/querying.rb:37
             exec_queries at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/relation.rb:171
                     to_a at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/relation.rb:160
       logging_query_plan at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/explain.rb:41
                     to_a at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/relation.rb:159
                    first at d:/installed/Develop/Java/jruby-1.7.4/lib/ruby/gems
/shared/gems/activerecord-3.2.13/lib/active_record/relation/finder_methods.rb:11
7
                 __send__ at org/jruby/RubyBasicObject.java:1709
                    first at d:0
                   (root) at flow.rb:23

我用 JRuby 通过 ActiveRecord 连接过 DB2,你可以参考一下,方法如下:

安装 ActiveRecrod

gem install activerecord

安装 jdbc 适配器

gem install activerecord-jdbc-adapter

下载 DB2 的 JDBC 驱动

连接其他数据,就下载相应的驱动 JAR 包,并且把 JAR 包路径放到 CLASSPATH 环境变量中

连接 DB2

require 'active_record'

ActiveRecord::Base.establish_connection(adapter: "jdbc",
                                         driver: "com.ibm.db2.jcc.DB2Driver",
                                         url: "jdbc:db2://host-name:port/db-name",
                                         username: "username",
                                         password: "password")

class User < ActiveRecord::Base
end

puts User.find(1).name
  1. 只需要 require 'active_record'即可
  2. adapter 必须是 jdbc(所有通过 JDBC 连接的需要用 jdbc)

#1 楼 @redraiment 谢谢。

原因我已经找到了。使用的表中列名有rails magic field names,所以导致的问题。 用了一个 gem safe_attributes,就解决问题了。

#2 楼 @heliang7 原来如此,你是在重构遗留系统吗?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号