LoginSignup
1
0

More than 5 years have passed since last update.

active record gem

Last updated at Posted at 2017-04-14
  • Rails consoleで何か変更ある時、reload!でreloadする
> reload!
  • レガシーシステム(legacy system)がconvention over configurationに反する場合、カスタマイズできる点
class User < ActiveRecord::Base
  self.table_name = "USER"
  self.primary_key = "user_id"
  self.table_name_prefix = "hello_"
  self.table_name_suffix = "_tokyo"
end
  • column読む三つの方法
user.email
user[:email]
user.read_attribute(:email)
  • serializeとstoreので項目の値をyml、jsonでDBに保存する
    デメリットがあるので、慎重に検討!
    http://qiita.com/jnchito/items/68e91e9bf46f960a79e4

  • model objectの新規?DBから読み取った状態?削除状態?の判断
     DBの実際状態とは関係ない!?

user.new_record?
user.persisted? # DBから読み取ったrecord+まだdestroy処理を行ってない
user.destroyed? # DBから読み取った後、destroy処理を行った
  • model object作成
user = User.new do |user|
  user.name = "tom"
end
user.save
user.save!

User.create(name: "tom", email: "hoge@gmail.com")
User.create!(name: "tom", email: "hoge@gmail.com")
  • get with primary key
User.find(1) # throw RecordNotFound Exception if no record
User.find([1, 2]) # throw RecordNotFound Exception if some record can't be found.
  • convert model to Hash
user.attributes
  • modify attributes without saving
user.name = "xx"
user[:name] = "xx"
user.write_attribute(:name, "xx")
user.attributes = {name:"tt", email: "hoge@mail.com"} # update specified columns only
user.assign_attributes({name:"tt", email:"hoge"}) # update specified columns only
user.attributes[:name] = "xx" # user.attributes is not changed!! never use this.
  • modify attributes and save to DB
user.save
user.update(name:"kk",email:"xx@gmail.com")
user.update_attributes(name:"kk22",email:"xx22@gmail.com") # update_attributes is alias of update
user.update!(name:"kk",email:"xx@gmail.com")
user.update_attributes!(name:"kk22",email:"xx22@gmail.com")
user.update_attribute(:email, "xx") # update one attribute without validation, callbacks are executed, updated_at is changed
user.update_column(:email, "xx") # update one attribute without validation, callbacks are not executed, updated_at is not changed.
  • update and get model (will exec validation)
user = User.update(2, {email:"hello"})
# return model whether success or failure
#   or ActiveRecord::RecordNotFound
user.valid?

is similar to

user = User.find(2)
user.update({email:"hello"}) # return true or false
  • update all record (no validation here !!)
User.update_all({email:"xx",name:"xx"})
user.attributes_before_type_cast
user.read_attribute_before_type_cast(:created_at)
user.created_at_before_type_cast # "2017-03-27 05:16:50.821663"
user.created_at # Mon, 27 Mar 2017 05:16:50 UTC +00:00
  • clone vs dup

  • query cache
    Query is cached in a hash {SQL => result set]}
    If the SQL is exactly the same as SQL in cache, the cached result will be used.

ActiveRecord::Base.connection.disable_query_cache!

ActiveRecord::Base.connection.enable_query_cache!

ActiveRecord::Base.connection.clear_query_cache

ActiveRecord::Base.connection.uncached do # uncached in this block
   ....
end

ActiveRecord::Base.connection.cache do # cached in this block
   User.where("id =  1").first
   User.where("id =  1").first # get the Result in cache
   User.where("id =    1").first # not exactly the same!
end

ActiveRecord::Base.connection.instance_variable_get(:@query_cache) # get current cache
  • readonly attributes you can set readonly attributes, but the changes will never be saved to DB
class User < ApplicationRecord
  attr_readonly :email
end
  • Delete destroy will load instance first and then calls destroy on it.
user.destroy
user.destroy!
User.delete(1)
User.delete([1])
User.destroy(1)
User.destroy([1,2])
  • Optimistic Locking add *lock_version column to table first
  add_column :users, :lock_version, :integer, default: 0

When lock_version is changed, the update will rails ActiveRecord::StableObjectError.

  • basic where conditions
Product.where(sku: 11) # where sku = 11
Product.where(sku: [1,2,3]) # where sku in (1,2,3)
Product.where(sku: []) # where 1=1
Product.where(sku: [1]) # where sku=1
Product.where('descript like ? and color = ?', "%xx%", "red")
Product.where("sku in (?)", [1, 2, 3])
  • where with bind variables
User.where("name = :xx and location = :xx", xx: "superman")
  • where (not equal and not in)
Product.where.not(name: "x") # name != "x"
Product.where.not(sku: [1,2]) # sku not in (1,2)
  • where (boolean)
User.where('active = ?', true)
  • where(is null)
User.where(email: nil)
User.where.not(email: nil)
  • order clause
User.order("name desc, email asc")
User.order(name: :desc, email: :asc) # use different cache key to above one
  • limit and offset
User.limit(10).offset(10)
  • select column
User.select("*", "salary * 2 as bonus").fisrt.bonus
  • from
def self.find_xxx
  select("users.*").
    from("users, locations").
    where("xxxxxx")
end
  • check the existence of records
User.exists(1)
User.exists(name: "xx")
Use.where(admin: true).exist?
@posts = current_user.visible_posts.where(name: params[:name])
# => the visible_posts method is expected to return a chainable Relation

def visible_posts
  case role
  when 'Country Manager'
    Post.where(country: country)
  when 'Reviewer'
    Post.published
  when 'Bad User'
    Post.none # => returning [] instead breaks the previous code
  end
end
  • order, reorder, reverse_order

  • uniq/distinct

User.select(:sex).uniq # select distinct sex from users
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0