Rails ActiveRecord いろいろ

仕事柄プルリクをレビューすることが多々あるのですが、やっぱりまだまだわかっていないことが多い… 忘れないようにメモメモ…

inverse_of

inverse_of を指定したリレーションのある2つのモデルでは、双方から同一のインスタンスを参照することができる。 つまり、双方ともメモリ上では同じインスタンスとして扱われる。 inverse_of の設定がないと同一のインスタンスとしては扱われず、一方からの変更がもう一方から参照されても変更されていない ふむふむ…

class User < ActiveRecord::Base
  has_many :menus
end

class Menu < ActiveRecord::Base
  belongs_to :user
end
user = User.first
menu = user.menus.first
user.name == menu.user.name # => true
user.name = "change"
user.name == menu.user.name # => false

Userのフィールド name の変更が、Menu からたどった時に変更が参照されていない。メモリ上では別インスタンスとして扱われているからである。

inverse_of を指定してあげる

class User < ActiveRecord::Base
  has_many :menus, inverse_of: :user
end

class Menu < ActiveRecord::Base
  belongs_to :user, inverse_of: :menus
end

メモリ上では同一インスタンスとして扱われるようになるので、user もしくは user.menuから name を変更しても以下の結果になる

user.name == menu.user.name # => true

すげーな!

change_column_null

ActiveRecordでcolumnにNotNull成約をかけてしまったけども、後々になってやっぱり制約を外したい…なんてときに使います。

class ChangeColumnToUser < ActiveRecord::Migration[5.1]
  def change
    change_column_null :users, :name, true
  end
end
change_column_null table名, column名, true/false

Ruby勉強し直してみた 1

Railsエンジニアになってはや1年が経とうとしています。そんな中で最近思うのですが「Railsはわかってきたけれども、Rubyが全くわからない…」 これはやべぇと思い、ここで改めてRubyを勉強し直していきます その備忘録

Ruby演算子

ruby演算子には優先度があります

高い  !
    &&
    ||
    not
低い  and or

優先度があることにより、英語の論理演算子と記号の論理演算子を混在させてしまうと、求めたい結果が変わってしまうことがある

a = true
b = false
!a || b
not a || b

↓このように評価される

(!a) || b
not (a || b)

ふむふむ。 また記号の論理演算子と違い、英語の論理演算子同士の場合は優先順位の違いがない。 ()をつかわなければ左から右に順番に評価されていく

a = true
b = true
c = false

# && の方が || より優先順位が高い
a || (b && c)

# and or は優先順位が同じなので左から評価されていく
(a or b) and c

記号と英語の演算子で優先順位に違いがあるため and or を && || の代わりに使おうとすると期待と違う形になるやも

and や or は条件分岐で使うのではなく、制御フローを扱うのに向いている 例えば 「正常なuserであればメールを送信する」という制御フローを実行したければ

user.valid? and send_mail_to user

というように書くことができる

or も「Aが真か? 真でなければBせよ」という制御フローを実現することに向いている

# userが不正だったらエラーメッセージを返す
user.valid? or return 'userが不正です'

三項演算子

n = 11
if n > 10
  '10より大きい'
else
  '10以下'
end
=> "10より大きい"

こんな風にかける

n = 11
n > 10 ? '10より大きい' : '10以下'
=> "10より大きい"

シンプルなif/else文であればこの書き方のほうがスッキリと書くことができる

改めてRuby勉強するとおもしろい…!

Go langでFizzBuzz

田舎育ちのエンジニアです Go lang気になってたのでちょっと勉強始めてみました 備忘録です。

Go langとは

Go言語は2009年にGoogleによって作られたオープンソースの静的言語です。 特徴としては ・ シンプル

・ コンパイル・実行速度が早い。

・ 安全性が高い。

・ 同期処理が容易に行える。

などなど…

ちなみに調べる時は「Go」だけでなく「Go lang」、「Go言語」と検索したほうが良いです

FizzBuzz

プログラマーの人ならだいたい書いたことのあるFizzBuzzをGo langで書いていきます。

package main

import "fmt"

func main() {
    n := 0
    for {
        n++
        if n > 15 {
            break
        }
        switch n {
        case 15:
            fmt.Println("FizzBuzz")
        case 5, 10:
            fmt.Println("Buzz")
        case 3, 6, 9, 12:
            fmt.Println("Fizz")
        default:
            fmt.Println(n)
        }
    }
}

こんな感じで書くことができるのですが、Go langのcase文では値だけでなく式を指定することもできます 少し変更を加えると

package main

import "fmt"

func main() {
    n := 0
    for {
        n++
        if n > 15 {
            break
        }
        switch {
        case n%15 == 0:
            fmt.Println("FizzBuzz")
        case n%5 == 0:
            fmt.Println("Fizz")
        case n%3 == 0:
            fmt.Println("Buzz")
        default:
            fmt.Println(n)
        }
    }
}

うん。こっちの方がなんか良い!

まだGo langをはじめて数日ですが、おもしろいと感じています。

これからも雑でもアウトプットは出していきたい…