ActieRecordには様々なメソッドがあります。中にはあまり使わないものもあると思います。以下に個人的な覚え書きの意味もこめて、幾つかのメソッドの使い方や発行されるSQLを載せます。
##uniq
SQLのdistinctに相当します。
pry(main)> User.where(name: 'test').uniq
User Load (0.1ms) SELECT DISTINCT "users".* FROM "users" WHERE "users"."name" = 'test'
##merge
ActiveRecordでJOINを使ってデータを取得する場合、以下のようにjoinメソッドを使って書く事ができます。
User.joins(:auth_providers).all.where(auth_providers: { provider: 'facebook' })
これは次のようなSQLを発行します。
SELECT "users".* FROM "users" INNER JOIN "auth_providers" ON "auth_providers"."user_id" = "users"."id" WHERE "auth_providers"."provider" = 'facebook'
これと同じことをmergeメソッドを使って書く事ができます。
まずscopeを書きます
class AuthProvider < ActiveRecord::Base
belongs_to :user
scope :facebook, -> { where(provider: 'facebook') }
scope :developer, -> { where(provider: 'developer') }
end
mergeメソッドでは、ここで定義したscopeを使います。上で上げたjoinと同じSQLを発行するには次のように書きます。
User.joins(:auth_providers).all.merge(AuthProvider.facebook)
where(auth_providers: { provider: 'facebook' })と書いていた箇所がスッキリしますね。
最初mergeっていうメソッド名だったので、違う動きを想像していました。
##rewhere
メソッド名から動きを想像出来るでしょうか?百聞は一見に如かずなのでコードを見てみましょう。
pry(main)> User.where(name: 'test')
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."name" = 'test'
rewhereを使うと
pry(main)> User.where(name: 'test').rewhere(name: 'hoge')
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."name" = 'hoge'
分かりますでしょうか?where(name: 'test')が上書きされます。
例えばdefault_scopeとかで指定されている条件を変更したい時などに使うのでしょかね。
##reorder
これも名前から想像できるでしょうかね?発行されるSQLを載せます
pry(main)> User.all
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC
default_scopeでorder(id: :desc)を指定ししている場合にreorderを使ってやると
pry(main)> User.all.reorder(id: :asc)
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC
ORDER BYのところが書き変わっていますね。
##reverse_order
習得したデータを並び替えます。
pry(main)> User.all.order('name')
User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY name
=> [#<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">]
reverse_orderを使うと・・。
pry(main)> User.all.order('name').reverse_order
User Load (3.9ms) SELECT "users".* FROM "users" ORDER BY name DESC
=> [#<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">]
##take
一件だけデータを取得します。
[6] pry(main)> User.take
User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1
=> #<User id: 1, name: "naka", email: "naka5313@gmail.com", provider: "developer", nickname: nil, access_token: nil, secret_token: nil, created_at: "2014-11-26 15:36:12", updated_at: "2014-11-26 15:36:12", image_url: nil, uid: "naka5313@gmail.com">
以上です。また何かあれば追記します。