rubyでデザインパターン decoratorパターン

class Coffee

  #価格
  def getCost
  end

  #商品説明
  def getDescription
  end
end

class SimpleCoffee < Coffee
  def getCost
    10
  end

  def getDescription
    'Simple coffee'
  end
end

class MilkCoffee < Coffee
  def initialize(coffee)
    @coffee = coffee
  end

  def getCost
    @coffee.getCost + 2
  end

  def getDescription
    "#{@coffee.getDescription}にミルクを加えました。"
  end
end

simple_coffee = SimpleCoffee.new
milk_coffee = MilkCoffee.new(simple_coffee)
puts simple_coffee.getCost
puts milk_coffee.getCost

puts simple_coffee.getDescription
puts milk_coffee.getDescription

#こうやって出力されます
#10
#12
#Simple coffee
#Simple coffeeにミルクを加えました。

このように基本はSimpleCoffeeだけど、ときどき機能を拡張するみたいな時に使えるパターン

Rubyでデザインパターン proxyパターン

class Door

  def open
    puts 'open door!'
  end

  def close
    puts 'close door!'
  end

end

class SecurityDoor

  def initialize(door)
    @door = door
  end

  def open(password)
    if password == 'open goma!'
      @door.open
    else
      puts 'password fail'
    end
  end

  def close(password)
    if password == 'close goma!'
      @door.close
    else
      puts 'password fail'
    end
  end

end


door = Door.new
security_door = SecurityDoor.new(door)

security_door.open('valid_password!')
security_door.open('open goma!')

DoorクラスをラップするSecurityDoorクラスを定義しています。
そこでパスワードを確認する処理を挟んで本来アクセスしたいであろうDoorクラスへのアクセスを制御しています。
ここがポイントでアクセス制御がproxyパターンの目的です。
場合によってはdecoratorパターンと実装がかなり似ることがありますが目的が違います。
proxyパターンの目的はアクセス制御
decoratorパターンの目的は機能の追加です。

Rubyによるオブジェクト指向 8章 コードサンプル

 
attr_reader :size, :parts

def initialize(args={})
 @size = args[:size]
 @parts = args[:parts]
end

def spares
 parts.spares
end

end

class Part
 attr_reader :name, :description, :needs_spares

 def initialize(args)
  @name = args[:name]
  @description = args[:description]
  @needs_spares = args.fetch(:needs_spares, true)
 end
end

class Parts
 attr_reader :parts

 def initialize(parts)
  @parts = parts
 end

 def spares
  parts.select { |part| part.needs_spares }
 end

end


chain = Part.new(name: "chain", description: "10-speed")
road_tire = Part.new(name: 'tire_size', description: "23")

road_parts = Parts.new([chain, road_tire])

road_bike = Bycycle.new(
size: 'L',
parts: road_parts
)

puts road_bike.size
puts road_bike.spares.size

rails route 自分用メモ

namespace :api do
 scope module: 'weather' do
  get 'weather'
 end
end
 
URLが/api/weatherでapi/weather_controllerのweatherアクションに
ルーティングしたい場合はこうやってかく
 
namespaceがURLもcontrollerも追加、scope moduleはURLだけ scopeはcontrollerだけ
 

SQL 自分用まとめ

DESTINCT

SELECT DISTINCT 入金額
FROM 家計簿

みたいにDISTINCTは列名を指定して使う

SELECT DISTINCT 入金額, 費目
FROM 家計簿

 みたいに2つ列を指定するとこの2つが同じだったら取り除かれるようになる。
selectされた列にDESTINCTされるイメージをもつ。

ORDER BY

SELECT * FROM 家計簿
ORDER BY 入金額 DESC, 出金額 DESC
見たいに最後に使う。
order by に2つの列を指定すると1つ目の列でソートされた後に
その1つ目の列が同じあたいのものに関しては2つ目の列でソートされる。

UNION

共通のカラムをもつテーブル2つを繋げる
SELECT 費目, 入金額, 出金額 FROM 家計簿
 UNION
SELECT 費目, 入金額, 出金額 FROM 家計簿アーカイブ
UNIONにORDER使うときは列番号指定でソートした方が良い。
列名で指定する場合は1つ目のselect文のものを指定する。

集計関数

集計関数は基本的にselect文の中でしようする。 sum max min avg count DBの種類によって違うが基本的にこの5種類 集計関数は集計の対象となった全ての行に対して1回だけ計算を行う。 よって結果表は必ず一行になる。 count()とcount(列名)の違いはが全ての行を数えるのに対し、(列名)はnullの行を 無視してカウントする。 覚えておくテク 重複を除いたcount SELECT COUNT(DISTINCT 費目) FROM 家計簿

git 他の人のブランチで作業したい場合。

gitで開発中にバックエンドの実装をAさんがしてフロントはBさんにお願いするとなった場合にAさんのブランチから新たなブランチを切ってBさんが作業するか Aさんのブランチでそのまま作業するかはチームの方針によると思いますが、 今回は後者のパターン。

前提としてAさんのブランチはリモートにpush済みであるとする。(Aさんのブランチ名はtestとする) 以下、Bさんが行うコマンド

git fetch

git checkout origin/test

#いろいろ作業してコミットしたあとに

git push origin HEAD:test

これでAさんの最後のコミットから続けてBさんがコミットできます。

自分用メモ Rubyで気をつけること

requireとrequire_relativeの違いはファイルパスの起点となる場所の違い。

requireはrubyを実行しているディレクトリが起点になる。relativeはファイルの置かれている場所が起点になる。

 

for文使わない点が独特。配列なんかに対して繰り返せって感じのメソッド呼ぶことで繰り返しを記述する。

 

範囲オブジェクトをデフォルトでサポート

 

rubyがreturnを省略した際に返す値は、rubyvmのスタックに最後に積まれた

 

クラスとは別にモジュールという概念がある。

メソッドをグループ化してクラスに取り込みやすくしたもの

 

新規アプリ作成(vue込み)

rails new todo_sample --webpack=vue

bin/rails g controller home index

 

 

rails5.2系でCSRF対策を無効にするには、application_controller.rbに

protect_from_forgery

を追記。