#author("2017-03-16T17:50:32+09:00","default:wikiwriter","wikiwriter")
&tag(ActiveRecord);
*目次 [#t9585ef4]
#contents
*参考情報 [#xd595ebe]
-[[読書メモ+tips+日記:[Ruby] ActiveRecord を単体で(Railsアプリの外で)使う:http://blog.livedoor.jp/takaaki_bb/archives/50602246.html]]
-[[ActiveRecord を 単独で使う例: katoy: cocolog:http://youichi-kato.cocolog-nifty.com/blog/2008/06/activerecord_0c49.html]]
-[[Active Record クエリインターフェイス | Rails ガイド:http://railsguides.jp/active_record_querying.html]]…ここが一番分かりやすい

*スコープ [#m621287a]
-おおむねstaticメソッドだがnilを返すとallとなるところが異なる。


*検索 [#pba5c11a]

**概要 [#wec34d52]
-[[Rails 4で非推奨になった/なっていないfinderメソッドを整理する - Qiita:http://qiita.com/jnchito/items/2b7d64851665071ed6e6]]
-[[rails/activerecord-deprecated_finders:https://github.com/rails/activerecord-deprecated_finders]]
-dynamic finderが全て非推奨になったわけではない(find_by_nameのような)。

**IDや項目で検索 [#wd1c188e]
-findを使う。レコードが存在しない場合例外発生
 book = Book.find(999)
-find_by_idを使う。レコードが存在しない場合nil。
 book = Book.find_by_id(999)
 book = Book.find_by_name('おもしろい本')
 book = Book.find_by_name!('おもしろい本') #=>例外発生たい場合
-find_by(ハッシュ)を使う。レコードが存在しない場合nil
 book = Book.find_by(id: 999)
 book = Book.find_by(name: 'おもしろい本')
 book = Book.find_by!(name: 'おもしろい本') #=>例外発生させたい場合
 book = Book.find_by(name: 'おもしろい本', price: 100) #=>2項目のAnd検索。


**whereで条件指定 [#x0fdb833]
-Are系は存在しない場合空配列となる。firstで先頭要素を取得する。
-whereで検索条件を指定できる
 book = Book.where("title=?", title).first
-複数条件を指定する場合
 book = Book.where("title=? AND price=?" title, price).first

**関連オブジェクトを使って検索 [#k3f0338f]
-includesやjoinsを使って検索できる。[[includes (ActiveRecord::QueryMethods) - APIdock:http://apidock.com/rails/ActiveRecord/QueryMethods/includes]]
-例えば以下の通り
#pre{{
users = User.includes(:address)
users.each do |user|
  user.address.city
end
User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
}}
-ここでincludesに指定するのは関連の名前(belongs_toやhas_manyで指定する名前)であるのに対し、referencesで指定するのはテーブルの名前(複数形の名前)でないといけないことに注意。whereの中に記述するのもテーブル名。
-referencesはテーブル参照が必要なことを明示している。これは例えばメールアドレスを検索する場合にドットが含まれている場合にまずいのの対策らしい。[[【Rails3.2】【バッドノウハウ】includes 使用時に where で ドットを使うと想定外になるかも知れない件、または、なぜRails4 から references が必要になったのか - MUGENUP技術ブログ:http://mugenup-tech.hatenadiary.com/entry/2014/04/14/144759]]
*保存 [#d162a6c4]

**保存時に検証処理をバイパスする [#yb717c8a]
-saveメソッドに"validate: false"を指定する。
 @product.save(validate: false)

*削除 [#ibe258c8]

**全削除系 [#e98e0319]
***delete_allとdestroy_allの違い [#xa80c52a]
-delete_allは関連を削除せずActiveRecordを介さないので高速。
-destroy_allは関連を削除するためにActiveRecordを介するので低速。

***パラメータの指定 [#a8368bf7]
-whereで検索してからdelete_all or destroy_allすればよい
 Manager.where(:manager_level => 5).destroy_all

*Tips [#za8f7a18]

**保存済みレコードかどうかの確認 [#a1b055eb]
-new_record? 新規データの場合はtrue。
 item.new_record?
-persisted?保存済みの場合はtrue。
 item.persisted?
**複数のデータベースに接続する [#jdc8bc0c]
-ActiveRecord::Baseを継承したクラスでestablish_connectionをそれぞれ設定する。
#pre{{

class OldPerson < ActiveRecord::Base
  self.table_name = 'person'
  self.inheritance_column = :old_type
  self.establish_connection(:adapter=>"mysql2",:host=>"localhost",:username=>$dbuser,:password=>$dbpasswd,:data\
base=>$olddbname)

end

class Person < ActiveRecord::Base
  self.inheritance_column = :old_type
  self.establish_connection(:adapter=>"mysql2",:host=>"localhost",:username=>$dbuser,:password=>$dbpasswd,:data\
base=>$newdbname)
end
}}

**type列がエラーになる [#k2b54f44]
-self.inheritance_column = :old_typeのようにして回避する
#pre{{
class OldPerson < ActiveRecord::Base
  self.table_name = 'person'
  self.inheritance_column = :old_type
end
}}


**大量のINSERTを早くする [#j333ff18]
***バックエンドのDB設定をチューニングする [#efef9ed0]
-MySQLの場合my.cnfでinnodb_buffer_pool_sizeなどをいじる。
#pre{{
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
}}

***transactionを使う [#ub5ccc1e]
-saveなどをActiveRecord::Base.transaction do endで囲むとCOMMIT回数が減らせるので早くなる。

***activerecord-import [#bd26a5c1]
-[[zdennis/activerecord-import &#183; GitHub:https://github.com/zdennis/activerecord-import]]を使う。MySQLの高速化した(圧縮された)INSERT文を生成してくれる。これが一番効果あった。


**SQLを表示する [#x2a1fe33]
-loggerを使う。
#pre{{
require 'logger'
ActiveRecord::Base.logger = Logger.new(STDOUT)
}}


*トラブルシューティング [#i49c62fd]
** 「[deprecated] I18n.enforce_available_locales will default to true in the future」というメッセージ [#gb82f542]
-RailsではなくActiveRecord単体で使った時に表示されるようになった。スクリプトのどこかに以下を追加すればとりあえず回避できる。
 I18n.enforce_available_locales = false

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS