Acitve Recordについて

 
　:beginner:初めての投稿です。
・Ruby on Raisはかなり開発がスムーズに行えるフレームワークと聞く。中でもAcitve RecordはSQLをほとんど記述しないため、モデル 関係の開発がとてもスムーズに進むとされている。今回は、Acitve Recordの理解を深めていけるように、Acitve Recordでどういったことができるかをメモとして残しておく。


##Active Recoedとは
Ruby on Rails の一部として開発されているOR Mapper 
(O は Object、そして R は Relational database) というツール。
どういったメリットがあるかと言うと、
**Rubyを用いてDBからデータを探したり、持ってきたりすることができる。**
具体的には以下のようなメリットがあります。

### ActiveRecordのメリット
・**Rubyで直感的に書ける**

・**どのDBを使用してもRubyで統一できる**
##DBの準備
まずは、usersテーブルを作成。

```import.sql
create table users( 
  id integer primary key,
  name text,
  age integer,
  created_at,
  updated_at,
);
```
usersテーブルを作るため、import.sqlをDBに読み込ませる。



## Active Recordの設定
```main.rb
  require 'active_record'
  require 'pp'
  require 'logger' #Logger を使えば SQL の命令自体を確認することができる
  
  Time.zone_default = Time.find_zone! 'Tokyo'

  ActiveRecord::Base.default_timezone = :local
  
  ActiveRecord::Base.establish_connection(
  "adapter" => "sqlite3",
  "database" =>"./myapp.db"
)

class User < ActiveRecord::Base 

end
  
```

## レコードの挿入

###①クラスのインスタンスを作る
```main.rb
user = User.new
user.name = "tanaka" 
user.age = 23
user.save
```

### ②ブロックを使う
```main.rb
user = User.new do |u|
  u.name = "mochizuki"
  u.age = 18
end
  user.save

```

##レコードの抽出 (select find where)

```main.rb
#レコードの一番初め(first)を抽出
pp User.select("id, name, age").first

#id=3で抽出
pp User.select("id, name, age").find(3)

#id以外で探す
pp User.select("id, name, age").find_by(name:"Tanaka")

#whereで探す
pp User.select("id, name, age").where(age:[19,31])

#AND検索
pp User.select("id, name, age").where("age　>= 20 and age <30")

#OR検索
pp User.select("id, name, age").where("age　>= 20 or age >=30")

#NOT検索
pp User.select("id, name, age").where.not(id :3)


#変数を条件分岐に入れる（プレースホルダー）
pp User.select("id, name, age").where("age　>= :min or age >=:max,{min:min ,max:max}")

#文字列の部分一致(名前がiで終わる値を抽出)
pp User.select("id, name, age").where.("name like ?","%i")

```
##並び替え(order limit offset)

```main.rb
#orderで年齢順
pp User.select("id, name, age").order(:age)

#逆順番
pp User.select("id, name, age").order(:age :decc)

#limit件数制限
pp User.select("id, name, age").order(:age ).limit(3)

#offsetで1爪の値を飛ばして表示
pp User.select("id, name, age").order(:age ).limit(3).offset(1)

```

##抽出条件の登録

```main.rb
#クラスメソッドを使う
def self.top3
  select("id, name ,age").order(:age).limit(3)
end
```

##データの更新(update)

```main.rb
#idを使う
User.update(1,age:50) #id=1を指定して、ageを50に変更

#id以外を指定=>whereを使う
User.where.(name:"Tanaka").update(age:50)

#複数のデータ更新
User.where.("age >= 20").update(age:80)
```

##データの削除(deleteとdestroy)

```main.rb
#delete 単機能だけど高速 単にレコードを削除するだけなので
#destroy 高機能だけど若干低速 関連するオブジェクトを考慮してくれたりだとか、削除する前後でなんらかの自動処理を加えることもできるので

#delete idが1のデータを削除
User.delete(1)

```

##バリデーション

```main.rb
class User < ActiveRecord::Base 
  validate :name ,:age, :presence:true #レコードがないと保存できない
  validate :name ,length:{minimum:3} #長さが必ず３文字以上
end
```

##Callback

```main.rb
#Callbackは特定の処理が行われる前後で自動的になんらかの処理を噛ます仕組み(処理を考慮数するのはdestroy)

class User < ActiveRecord::Base 
  before_destroy :print_before_msg
  after_destroy :print_after_msg

protected 
  def print_before_msg
    puts "#{self.name}will be deleted"
  end
  def print_after_msg
    puts "#{self.name} deleted"
  end
end

User.where("age >= 20").destroy_all
#削除されるたびにbefore_msg,after_msgの呼び出しがされる
```

##Association
**userがコメントするアプリの想定**

```import.sql
  create table comments( 
    id integer primary key,
    user_id integer,
    body text,
    created_at,
    updated_at,
  );
```

**users、comments２つのテーブルを紐付ける**

```main.rb
class User < ActiveRecord::Base 
  has_many :comments
end

class comment < ActiveRecord::Base 
  belongs :user
end
```
**紐付けて抽出**

```main.rb
user = User.includes(:comments).find(1)
#includes(:comments)とすることで、comment情報も引っ張てきてくれる

#commentを軸にデータを引っ張ってくる
　　comments = Comments.includes(:user).all
```

##関連するデータの削除

```main.rb
User.find(1).destroy
#これだとid = 1のcommentは削除されない
```

```main.rb
class User < ActiveRecord::Base 
  has_many :comments ,dependent:destroy
end

```

##一通り復習してみて

事前に知っていた,**Validation、Association**はやはり大事な機能だと再認識した。
**dependent,destroy**の違いや、いつも使っているストロングパラメーターがCallbackの応用したものだったことなど初めて知った知識も多かった。