Tag: ActiveRecord

目次

参考情報

スコープ

  • おおむねstaticメソッドだがnilを返すとallとなるところが異なる。

検索

概要

IDや項目で検索

  • 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で条件指定

  • Active Record クエリインターフェイス | Rails ガイドが詳しい
  • whereで指定できる条件には、文字列、配列、ハッシュなど。
  • Are系は存在しない場合空配列となる。firstで先頭要素を取得する。
    book = Book.where("title=?", title).first
  • 文字列で検索したい場合
    books = Book.where("title='abc'")
  • 配列で検索。"?"でプレースホルダを指定できる。
    books = Book.where("title=? AND price=?" title, price)
  • ハッシュで指定。キーにフィールド、ハッシュ値にその値。複数指定した場合AND条件となる。
    books = Book.where(title: 'abc')
    books = Book.where('title' => 'abc')
    books = Book.where(title: 'abc', author: 'def')

関連オブジェクトを使って検索

並び替え

  • orderを使って並び替えることができる
    Book.order(:created_at)
  • ASC、DESCの指定(全てのレコードを対象とする場合.all.orderにしてなくてもよいらしい)。
    Book.order(created_at: :desc)
    Book.order(created_at: :asc)
    Book.order("created at DESC")
    Book.order("title DESC, created_at ASC")

個数制限

  • limitを使う
    Book.order(:created_at).limit(10)

保存

保存時に検証処理をバイパスする

  • saveメソッドに"validate: false"を指定する。
    @product.save(validate: false)

削除

全削除系

delete_allとdestroy_allの違い

  • delete_allは関連を削除せずActiveRecordを介さないので高速。
  • destroy_allは関連を削除するためにActiveRecordを介するので低速。

パラメータの指定

  • whereで検索してからdelete_all or destroy_allすればよい
    Manager.where(:manager_level => 5).destroy_all

Tips

保存済みレコードかどうかの確認

  • new_record? 新規データの場合はtrue。
    item.new_record?
  • persisted?保存済みの場合はtrue。
    item.persisted?

複数のデータベースに接続する

  • ActiveRecord::Baseを継承したクラスでestablish_connectionをそれぞれ設定する。
    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列がエラーになる

  • self.inheritance_column = :old_typeのようにして回避する
    class OldPerson < ActiveRecord::Base
      self.table_name = 'person'
      self.inheritance_column = :old_type
    end
    

大量のINSERTを早くする

バックエンドのDB設定をチューニングする

  • MySQLの場合my.cnfでinnodb_buffer_pool_sizeなどをいじる。
    innodb_buffer_pool_size = 512M
    innodb_log_file_size = 128M
    

transactionを使う

  • saveなどをActiveRecord::Base.transaction do endで囲むとCOMMIT回数が減らせるので早くなる。

activerecord-import

SQLを表示する

  • loggerを使う。
    require 'logger'
    ActiveRecord::Base.logger = Logger.new(STDOUT)
    

トラブルシューティング

モデルクラスに実装したメソッド内でアトリビュートにアクセスしたらローカル変数とみなされる

  • ruby on rails - Setting attribute from model without using self doesn't work - Stack Overflowにあるような例。例えばDeviceクラスのprepareメソッドでfull_nameを設定したいとする
    class Device < ActiveRecord::Base
      def prepare
        full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
      end
    end
    
  • 上の場合full_nameはローカル変数とみなされて、Deviceのfull_name属性に設定したとはみなされない。これを避けるためには次のようにしないといけない。
    class Device < ActiveRecord::Base
      def prepare
        self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
      end
    end
    
  • setterの場合は最初からローカル変数とみなされそこで終了するのに対し、getterの場合はローカル変数が存在しないとメソッドが検索される。
  • 結論。setterにはselfが必要。getterには不要。

「[deprecated] I18n.enforce_available_locales will default to true in the future」というメッセージ

  • RailsではなくActiveRecord単体で使った時に表示されるようになった。スクリプトのどこかに以下を追加すればとりあえず回避できる。
    I18n.enforce_available_locales = false

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-06-01 (木) 18:45:58 (655d)