query: tag:ActiveRecord

Ohm を使っていると色々と不満な点が見えてきます

  • @attributes を得る手段がない (#attributes が column_names を返す)
  • create!, save! がない
  • first, all がない
  • ...

これは AR 脳というよりも、ARの洗練されたAPIと比べてしまうと、
Ohm の未成熟さが浮き彫りになってしまうためだと思います。

ohm-arfreaks

そこで、ARのメソッドをOhm上で使えるようにしたラッパーを作成しました。

http://github.com/maiha/ohm-arfreaks

インストール

shell>>
% gem install ohm-arfreaks
<<--

ruby>>
require 'ohm'
require 'ohm-arfreaks' # これを追加

class Video < Ohm::Model
attribute :url
set :tags
end

Video.create!(:url=>"a")
Video.first.attributes
=> {:url=>"a", :tags=>[]}
<<--

以下のメソッドが利用可能です (0.1.0 現在)

  • self.primary_key
  • self.columns
  • self.column_names
  • self.content_columns
  • self.columns_hash
  • self.create!
  • save!
  • self.first
  • self.last
  • self.count
  • self.delete_all
  • new_record?
  • attributes

ARと比べると使えるメソッドは少ないですが、
これだけでも随分Ohmが快適になると思います。

backup

例えば、redis はどこに DB を作っているかわかり辛いので
時々バックアップが欲しくなるのですが、
昔懐かしのar_fixtures plugin 相当のことは以下のコードでできるようになります。

ruby>>
File.open("videos.yml", "w+") do |f|
hash = Video.all.inject({}){|h,v| h[v.id]=v.attributes;h}
f.print hash.to_yaml
end
<<--

posted by maiha maiha on Tue 16 Mar 2010 at 18:58 with 0 comments

(以下は PostgreSQL を例にしてますが、他のドライバでも通用すると思います)

install

まずは JRuby 用のドライバをインストールします。

shell>>
% gem install activerecord-jdbcpostgresql-adapter
<<--

設定

通常は database.yml に "adapter: jdbcpostgresql" と記述して利用するのですが、ここでは別の方法を紹介します。
内容は簡単で以下のコードを評価するだけです。

ruby>>
if RUBY_PLATFORM == "java"
require "active_record/connection_adapters/jdbcpostgresql_adapter"
end
<<--

(Railsであれば "config/initializers/jruby_compat.rb" などに記述しておくとよいでしょう)

メリット

  • MRI と同じアダプタ名 "postgresql" を利用できる
  • 変更なしで MRI, JRuby のどちらでも動作する

実行例

shell>>
% rvm use system
% ./script/console

User.count
=> 6

User.connection.class
=> ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

% rvm use jruby
% ./script/console

User.count
=> 6

User.connection.class
=> ActiveRecord::ConnectionAdapters::JdbcAdapter
<<--

JRuby はまだ発展途上ですので、
開発や挙動確認で MRI を利用する局面が多々あります。
そんな折、この方法であればいちいち database.yml の内容を変更する必要がないため、非常にシームレス&快適に利用できると思います。

posted by maiha maiha on Mon 18 Jan 2010 at 23:16 with 0 comments

例えばselect結果をinsertするような場合は効率面からActiveRecordを通さずそのままSQLを実行したい。select結果が数千件ある場合ARで素直に書くとそのまま数千回insert実行しなきゃならんので。

Railsでは基本ARで操作できるけど必要があればSQL書ける柔軟な所がある。
今回の場合ActiveRecord::Base::connection::executeを使用する。
Railsレシピブックで言うとP239の例。

ruby>>
Class Entry < ActiveRecord::Base
def self.select_insert_hogehoge
sqlstr = "hogehoge"
return connection.execute(sqlstr)
end
end
<<ruby

posted by ysakaki ysakaki on Thu 28 Aug 2008 at 15:53 with 0 comments

プラグインを作るのに手間取ったのでメモ。
ARに機能を追加させるようなプラグインのテストを書く際、AR派生クラスをnewしてメソッドを呼び動作を確かめたりしたくなります(私の場合、privateメソッドを呼びたくなった)。でもテストのためだけにテーブルを作るのはばからしい。でMockを使う方法、ARのテスト用Mockの登場です。

ポイントとしては、MockBaseで一旦ARを派生させてから、MockBaseを派生させたクラスを作るのがミソです。そうすることで他のテストに影響を与えないようにすることができます(tips from takiuchi)。

あともう一つ、environment.rbをズズーっとロードすることでRails全体を読み込むことができます。それによってARを使えるようになります。

rails>>
#acts_as_notifiable_test.rb
begin
require File.dirname(FILE) + '/../../../../config/environment'
rescue LoadError
require 'rubygems'
gem 'activerecord'
require 'active_record'
end

class MockBase < ActiveRecord::Base; end
MockBase.class_eval do
alias_method :save, :valid?
def self.columns() @columns ||= []; end

def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type, null)
end
end

class MockModel < MockBase
acts_as_notifiable :callback => :after_create, :message => "hello", :recipients => "test@gmail.com"
end

class ActsAsNotifiableTest < Test::Unit::TestCase
def test_option_message_string
assert_equal "hello", MockModel.new.instance_eval{jabber_message}
end
<<--

###Reference

posted by satoko satoko on Thu 6 Mar 2008 at 10:59 with 0 comments