LoginSignup
1
1

More than 5 years have passed since last update.

ActiveRecord 学んだ事まとめ

Last updated at Posted at 2018-09-01

学んだ事を追記していきます。

【参考】ActiveRecord入門

whereメソッド

whereメソッドはActiveRecordメソッドのうちの一つです。モデル.where(条件)のように引数部分に条件を指定することで、テーブル内の条件に一致したレコードのインスタンスを配列型で取得できます。

また、whereメソッドを連続して記述することによって、複数の条件に一致したレコードを取得することもできます。

[1] pry(main)> Tweet.where('id < 3')
  => [#<Tweet id: 1, image: "test1.jpg", text: "いい景色だ。", created_at: "2014-12-06 00:00:00", updated_at: "2014-12-06 00:00:00", user_id: 1>,#<Tweet id: 2, image: "test2.jpg", text: "Thank you!", created_at: "2014-12-07 00:00:00", updated_at: "2014-12-07 00:00:00", user_id: 2>]
  # idが3未満のtweetsテーブルのインスタンスを配列で取得

  [2] pry(main)> Tweet.where('id < 3').where(user_id: 1)
  => [#<Tweet id: 1, image: "test1.jpg", text: "いい景色だ。", created_at: "2014-12-06 00:00:00", updated_at: "2014-12-06 00:00:00", user_id: 1>]
  # idが3未満かつuser_idが1のtweetsテーブルのインスタンスを配列で取得

アソシエーション

アソシエーションとはモデル間の関連付けを管理する機能のことで、定義しておくことでモデルをまたいだデータの呼び出しをより簡単に行うことができるようになります。

アソシエーションを利用するために、まずはモデル間の関係を定義しましょう。アソシエーションを利用するには以下の2つの条件を満たす必要があります。

① モデルクラスにhas_manybelongs_toなどの定義がされている

② 所属する側のテーブルに所属するクラス名_idというカラムがある

例えばツイッターの投稿者とツイートは下記のような関係です。

image.png

image.png

Userモデルの視点で考えると、あるuserの作成したtweetが複数個ある状態と言えます。この状態のことをhas manyの関係といい、今回の場合には「User has many Tweets」の状態であると言えます。

User.rb
class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :tweets
end

また、Tweetモデルの視点で考えると、全てのtweetはいずれかのuserに属している状態と言えます。この状態のことをbelongs toの関係といい、今回の場合は「Tweet belongs to User」の状態であると言えます

Tweet.rb
class Tweet < ActiveRecord::Base
  belongs_to :user
end

アソシエーションを定義すると、モデルをまたいだデータの呼び出しをより直感的に行うことができます。

例えば、下記のように簡潔に書けます。
従来の場合
whereメソッドを使用

$ rails c  
[1] pry(main)> user = User.find(1)
[2] pry(main)> Tweet.where(user_id: user.id)
=> [#<Tweet id: 1, image: "http://photo1.jpg", text: "いい景色だ。", created_at: "2014-12-06 09:00:00", updated_at: "2014-12-06 09:00:00", user_id: 1>,
#<Tweet id: 1, image: "http://photo2.jpg", text: "楽しい思い出は消えない。", created_at: "2014-12-06 10:00:00", updated_at: "2014-12-06 10:00:00", user_id: 1>]

アソシエーション利用した場合
Userモデルに「User has many Tweets」の状態のアソシエーションを定義したので、Userモデルのインスタンス.tweetsと記述するだけでそのインスタンスが所持しているツイートを取得することができます。

$ rails c
[1] pry(main)> user = User.find(1)
[2] pry(main)> user.tweets
=> [#<Tweet id: 1, image: "http://photo1.jpg", text: "いい景色だ。", created_at: "2014-12-06 09:00:00", updated_at: "2014-12-06 09:00:00", user_id: 1>,
#<Tweet id: 1, image: "http://photo2.jpg", text: "楽しい思い出は消えない。", created_at: "2014-12-06 10:00:00", updated_at: "2014-12-06 10:00:00", user_id: 1>]

ポリモーフィック関連

ポリモーフィックは、関連付けのやや高度な応用です。ある1つのモデルが他の複数のモデルに属していることを、1つのアソシエーション定義だけで表現することができます。例えば、画像をアップロードして、ユーザーの画像や企業の画像に設定できるサービスがあるとします。アップロードされた画像は、ユーザーの画像もしくは企業の画像として紐付けられます。
image.png

class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

class Company < ActiveRecord::Base
  has_many :images, as: :imageable
end

class User < ActiveRecord::Base
  has_many :images, as: :imageable
end

テーブルのカラムは以下の通り。
image.png

ActiveRecord コールバック

ActiveRecordコールバックとは、作成/保存/更新/削除/検証/等、特定のイベント発生時に呼び出されるメソッドのことです。

利用可能なコールバック

オブジェクトの作成

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_create
  • around_create
  • after_create
  • after_save

オブジェクトの更新
  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_update
  • around_update
  • after_update
  • after_save

オブジェクトのdestroy

  • before_destroy
  • around_destroy
  • after_destroy

updateメソッド

updateはActiveRecordメソッドのうちの一つです。updateメソッドはモデルのインスタンスに対して使用することで、引数内の情報にレコードを更新することができます。

【例】

[1] pry(main)> tweet = Tweet.create(user_id: 1, text: "Hello", image: "test.jpg")
=> #<Tweet id: 1, user_id: 1, text: "Hello", image: "test.jpg", created_at: "2014-12-10 00:00:00", updated_at: "2014-12-10 00:00:00">
[2] pry(main)> tweet.update(text: "Thank you!")
=> true
[3] pry(main)> tweet
=> #<Tweet id: 1, user_id: 1, text: "Thank you!", image: "test.jpg", created_at: "2014-12-10 00:00:00", updated_at: "2014-12-10 00:01:00">

first_or_initializeメソッド

whereメソッドとともに使うことで、whereで検索した条件のレコードがあればそのレコードのインスタンスを返し、なければ新しくインスタンスを作るメソッドです。

【例】

user = User.where(nickname: "Shinbo").first_or_initialize
=> #<User id: 1, nickname: "Shinbo">

orderメソッド

データベースからデータ取得時にデータをどう並び替えるかというのが指定できます。
引数には並び替える基準のカラムと、DESC(降順)かASC(昇順)のどちらかの2つを指定することにより順番を指定して取得することができます。

モデル名.order('カラム名 順序')

limitメソッド

limitメソッド はデータをいくつ取得するかというのが指定できるメソッドで、引数には取得したい件数を指定します。

 モデル名.limit(取得件数)

averageメソッド

averageメソッドは、averageメソッドを利用するインスタンス取得先のテーブルのカラムを、シンボル型で引数にとります。その値の平均を、小数点ありの状態で返してくれます。

students = Student.all
  students.average(:score)
  #=> 小数点まで含んだ平均点

roundメソッド

利用した数字の小数点以下を四捨五入します。

10.4.round
  #=> 10

  10.5.round
  #=> 11

groupメソッド

テーブルのレコードを指定したカラムでまとめた状態で取得します。

【例】

Review.group(:product_id)
  Review Load (10.5ms)  SELECT `reviews`.* FROM `reviews` GROUP BY product_id
=> [#<Review id: 1, nickname: "まいき", rate: 1, review: "おもしろい", product_id: 21, created_at: "2014-11-05 16:03:39", updated_at: "2014-11-05 16:03:39", user_id: 4>,
  #<Review id: 3, nickname: "えいちゃん", rate: 10, review: "感動した!また見たい", product_id: 22, created_at: "2014-11-05 16:03:39", updated_at: "2014-11-05 16:03:39", user_id: 4>,
  #<Review id: 13, nickname: "ごとう", rate: 10, review: "思っていたより良かった", product_id: 23, created_at: "2014-11-05 16:03:39", updated_at: "2014-11-05 16:03:39", user_id: 4>

image.png

countメソッド

ountメソッドは配列などの要素数を返すメソッドです。groupメソッドに続けて使うとまとめられたそれぞれのレコードの数が取得できます。実行例は下記の通りです。

Review.group(:product_id).count
=> {21=>2, 22=>1, 23=>4}

order('count_カラム名').count(カラム名)

countメソッドの引数にカラム名を指定することができます。するとorderメソッドでcount_カラム名でのソートが可能となります。これはそのカラムを持つレコードの数でソートするという意味です。

keysメソッド

ハッシュはkeysというメソッドを持っています。これはハッシュのキーだけを取り出して配列として返すメソッドです。

mapメソッド

mapメソッドは配列クラスに定義されているインスタンスメソッドです。mapメソッドは配列の中身を1つずつ取り出してブロックという構文を繰り返し実行します。そして、ブロックの返り値を集めた新しい配列を作成します

配列オブジェクト.map {|ele| ブロックの処理}
  # eleには配列の要素が1つずつ代入される
  # ブロックの処理は配列の要素の数だけ繰り返し実行される
1
1
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
1