20201010_アウトプット(正規表現)

アプトプット画像

学んだこと

正規表現Ruby編)

  • 正規表現を用いることで、文字列の置換・抽出・制約調査ができる

Rubyにおいて、正規表現を利用するために重要な2つのメソッド(文字列)

メソッド名 役割
sub 置換
match 含まれているか確認(抽出・制約調査)
subメソッドについて
  • 第一引数に「置き換えたい文字列」を指定して、第二引数に「変換後の文字列」を指定する。
irb(main):001:0> str = "りんごを食べる"
=> "りんごを食べる"

irb(main):002:0> str.sub(/りんご/,"みかん")
=> "みかんを食べる"


matchメソッドについて
  • 指定した文字列が含まれている場合には、戻り値として「MatshData」というオブジェクトが表示される。

  • 含まれていない場合には、戻り値として「nil」が返される。

irb(main):001:0> str = "Hello, World"
=> "Hello, World"

irb(main):002:0> str.match(/Hello/)
=> #<MatchData "Hello">

irb(main):003:0> str.match(/Good/)
=> nil
  • MatchDataから実際にマッチした文字列を取り出したい場合には、配列を利用することで、取り出すことができる。
irb(main):001:0> str = "Hello, World"
=> "Hello, World"

irb(main):002:0> md = str.match(/Hello/)
=> #<MatchData "Hello">

irb(main):003:0> md[0]
=> "Hello"
Rubyのプログラムにsubやmatchなどを適用させるには▶︎if文を用いる
str = gets.chomp
if str.match(/good morning/)
  puts 'おはようございます!'
else
  puts 'あいさつが異なるようです。'
end

subメソッド(置換)を利用して、電話番号からハイフンを取り除こう

  • 「gsubメソッド」を使う。
メソッド 違い
sub 最初のマッチした対象のみ置換
gsub マッチする全てを置換
irb(main):001:0> tel = '090-1234-5678'
=> "090-1234-5678"

irb(main):002:0> tel.sub(/-/,'')
=> "0901234-5678"
# 最初のハイフンしか置換されない

irb(main):003:0> tel.gsub(/-/,'')
=> "09012345678"


matchメソッド(含まれるか)を利用して、パスワードに英数字8文字以上という制約を設定しよう

【英数字が8文字以上の時】
irb(main):001:0> pass = 'Hoge1234'
=> "Hoge1234"

irb(main):002:0> pass.match(/[a-z\d]{8,}/i)
=> #<MatchData "Hoge1234">
【英数字が8文字未満の時】
irb(main):001:0> pass = 'Hoge123'
=> "Hoge123"

irb(main):002:0> pass.match(/[a-z\d]{8,}/i)
=> nil

「matchメソッド」にプラスして、どの様にマッチしているか確認することができる。

パターン 役割
[a-z] 角括弧で囲まれた文字列いずれか1つがマッチするか
\d 数字がマッチするか
{n, m} 最低でn回、最高でm回出現するか(文字数制限)
i iを入れることで大文字・小文字を区別せずに検索
(付けないと全て小文字のみとなる)

補足:バックスラッシュは「オプションキー + ¥」(mac)


matchメソッド(含まれるか)を利用して、メールアドレスからドメイン部分のみ抽出しよう

irb(main):001:0> mail = 'hoge@gmail.com'
=> "hoge@gmail.com"

irb(main):002:0> mail.match(/@.+/)
=> #<MatchData "@gmail.com">

下記、2つのオプションを組み合わせて、「@から始まり、何かしらの文字が一回以上繰り返すものにマッチ」と抽出をかけられる。

パターン 役割
.(ピリオド) 全ての英数字においてどの1文字にもマッチ
+ ”+”の直前の文字が1回以上の繰り返しにマッチ

組み合わせることにより、もしも「@~」という文字列でない場合には、メールアドレスとして認めないという処理に応用できる。




正規表現Ruby on Rails編)▶︎バリデーションへの応用

郵便番号

  • 「3桁の数字」+「ハイフン」「4桁の数字」の構成である郵便番号が正しく入力しているか判別する。
irb(main):001:0> postal_code = "150-0044"

irb(main):002:0> postal_code.match(/\A\d{3}[-]\d{4}\z/)
=> #<MatchData "150-0044">
パターン 役割
\A \Aの直後においた文字が、「文字列の先頭」にある場合にマッチ
\z \zの直前においた文字が、「文字列の末尾」にある場合にマッチ
{数字} {}に囲まれた数字の回数があるとマッチ
Railsのモデルにこのように記入して使える!
validates :postal_code, format: { with: /\A\d{3}[-]\d{4}\z/, message: 'を入力してください' }



全角かな/カナの区別

irb(main):001:0> full_name = "山田はな子"

irb(main):002:0> full_name.match(/\A[ぁ-んァ-ン一-龥]+\z/)
=> #<MatchData "山田はな子">

irb(main):003:0> full_name = "yamadaハナ子"

irb(main):004:0> full_name.match(/\A[ぁ-んァ-ン一-龥]+\z/)
=> nil

文字列の先頭から末尾まで、「かな」あるいは「カナ」あるいは「漢字」であるか確認をしてしている。

パターン 役割
[ぁ-んァ-ン一-龥] かな/カナ/漢字であるかチェックする
Railsのモデルにこのように記入して使える!
with_options presence: true, format: { with: /\A[ぁ-んァ-ン一-龥]+\z/, message: '全角文字を使用してください' } do
  validates :first_name
  validates :last_name
  validates :first_name_kana
  validates :last_name_kana
end



passwordの英数混合の判断

passwordで活用するために、

  • 英数字が混合しているか

  • 少なくとも1回以上続き、末尾までそれが続くか

の2つの条件を作る。

irb(main):001:0> password = "T2o0k2y0o"

irb(main):002:0> password.match(/\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i)
=> #<MatchData “T2o0k2y0o”>
パターン 役割
?= "?="の後に書いた文字列とマッチしているか
.*? ".*?"のあとに続く種類の内容の文字がいくつかあるかもしれないし、ないかもしれない
Railsのモデルにこのように記入して使える!
PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze
validates_format_of :password, with: PASSWORD_REGEX, message: 'には英字と数字の両方を含めて設定してください' 

上記の正規表現の意味は、ざっくりいうと”「英字(大文字・小文字どちらでもOK)」と「数字」がぞれぞれ1文字以上ずつあるパスワードか?”という意味になる。

反対を言えば、

  • 「空白のみ」

  • 「"_"や"."などの英数字以外」

  • 「1だけ(英字がない)」

  • 「aだけ(数字がない)」

のような場合には「nil」になってしまう、ということ。



積み残し(復習したいところ)

  • devise rollback方法

  • カラム追加の方法

  • Rails勉強会



感想

正規表現についてぱっと見難しそうに見えたが、読み解いてみると、分かりやすくて面白かった。
学んでいて感じたことは、deviseでデフォルトで作成されるもの(emailやpassword)のバリデーションをアレンジしたいときはどうやってやるんだろうと感じた。(裏側で自動生成してくれて楽な分、普段使うアプリケーションはもっと色んな認証があるため)

バリデーションだけでなく、実際に入力したメアドに確認メールが送信され、そこからURL先に飛んだら、会員登録完了といった認証があるがそれはどうやってやるんだろうと思った。
調べてみると「PHP」の技術が必要そうだったので、カリキュラムを先に進めながら学んでいきたい。

20201009_アウトプット(ライブラリ・例外処理)

アプトプット画像

学んだこと

Rubyに用意された機能を呼び出す方法

  • あらかじめ用意された機能のカタマリを「ライブラリ」という。
標準ライブラリ 組み込みライブラリ 外部ライブラリ(gem)
Rubyに標準で用意 標準ライブラリの中でも特に利用頻度が高いもの 世界中の有志の
エンジニアによって提供
インストール不要 インストール不要 別途インストールが必要
date,fileutils,
csv,json,yaml
String ,Integer,
Array,Hash等
bundler,rails,rspec,
nokogiri,faker等
(記述)require 'ライブラリ名' (記述)require 'ライブラリ名' (ターミナル)「gem install gemの名前」後、
(記述)require 'ライブラリ名'



例外処理

  • 例外とは、プログラムで起こる予期しない問題のこと(つまり、エラー)

  • 例外が発生すると、それ以降の処理は中止されて実行されなくなる。

  • 例外処理とは、あらかじめ「例外」を予期しておき、その時に行う処理を定義すること。

  • RubyおよびRuby on Railsでは、「Exception」というクラスを継承することで、様々な例外が定義されている。(NoMethodError,SyntaxError等)

初期のダミーデータを作成する方法(seed)

  • テーブル作成後(rails db:migrate後)、そのカラムに対し、ダミーデータを作成するには、「seed」が便利!
(1)ターミナルで、以下のコマンドを実行すると、ダミーレコードを作るためのファイルが生成される。
% rails db:seed
(2)(1)のコマンド実行後に、どのようなダミーデータを作りたいかファイル内を編集する。
【db>seeds.rbの今回の記載内容】
users = []
10000.times do |i|
 # usersに10000件新規ユーザーの情報を格納する
  users << User.new(name: "dummy-#{i+1}", ticket_count: 0)
end
# importメソッドの引数に配列を渡して、まとめてレコードを作成する
User.import users
# 例外を仕込む
User.find(500).update(ticket_count: 2147483647)
  • 今回はこのファイルのために「activerecord-import」というGemを利用。

  • このGemおかげで、モデルが「importメソッド」を使用できる様になる。

  • 「importメソッド」とは、配列に大量の情報を格納して、その配列から情報を取りに行くことによって、1回のアクセスで大量のレコード作成ができるメソッド。



Rakeタスク

  • タスクを簡単に実行できるRubyのツール。

  • 利用することで、アプリケーションのタスクをコマンドで実行できる。

  • 今回定義する内容は「通常は一人10枚ずつチケットを配る」が、例外が発生した時に「10枚ずつチケットを配りつつ、例外が起きた人だけ別の処理を行う」場合と、「例外が発生したら全員に対して10枚配るのをやめる(その処理ごとなかったことにする)」場合について定義したい。

  • それぞれを定義し、実行されるか処理したい場合に、Rakeタスクが使える。(処理に際して、ダミーデータが必要なため、先ほどのseedが活きる)

(1)コマンドで、Rakeファイルを作成する
rails g task タスクファイル名

(2)作成されたファイルに処理を記述する

namespace :distribute_ticket do
  desc "全ユーザーのticket_countをrescueしながら10増加させる"
  task rescue: :environment do
    User.find_each do |user|
      begin
        user.increment!(:ticket_count, 10)
      rescue => e
        Rails.logger.debug e.message
      end
    end
  end

  desc "全ユーザーの中にticket_countが最大値のものを含んでいれば例外を発生させる"
  task raise: :environment do
    User.find_each do |user|
      begin
        if user.ticket_count > 2147483637
          raise RangeError, "#{user.id}は、チケット取得可能枚数の上限を超えてしまいます!"
   # raise 発生させたい例外クラス, 'エラーメッセージ'
        end
      rescue => e
        Rails.logger.debug e.message
      end
    end
  end

  desc "全ユーザーのticket_countをトランザクションで10増加させる"
  task transact: :environment do
    ActiveRecord::Base.transaction do
      User.find_each do |user|
        user.increment!(:ticket_count, 10)
      end
    end
  end
end
メソッド名 役割
namespace do ~ end 複数のタスクをグループ分けして1つにまとめる
desc 処理の説明。「description(説明)」の略。
task do ~ end タスクの内容
(3)タスクの実行
rails namespaceの名前:taskの名前

例外処理にあたって使うもの

  • 【begin】例外となりそうな箇所を囲い実行できる文法。

  • 【rescue】発生した例外を捕捉し、例外が起こった際に呼び出される条件節。処理を続けてはいけない例外でも処理してしまったり、意味のない例外処理を作る恐れがあるので、安易に使用しない。

  • 【raise】例外を発生させることができる文法。

  • トランザクション】一連の処理を一つにまとめて、処理が全て成功か、全て失敗かの状態を作ること。



積み残し(復習したいところ)

  • devise rollback方法

  • カラム追加の方法

  • Rails勉強会



感想

  • 10月8日から始めた「基本は朝やって、夜はのんびりする(自分のリフレッシュ)にする方針」について、かなり自分にあっている。

  • 理由は、睡眠の質がよくなったことと、今までは、残業してても、夜ご飯食べていても「勉強しなきゃ」という義務感にかられて焦っていた。「もう今日はやったから休もう」と気持ちを切り替えることによって、心がリフレッシュできて、プログラミングを楽しめるようになったこと。(最初の頃の気持ちを忘れかけていた気がする。)

  • あと、だんだんブログに書くことにも慣れてきた(マークダウン記法)。表など作るの早くなった(笑)アウトプットが目的だけど、もう少しコードとかは読みやすくしたいな。キータで見やすい人とかどのようにしているんだろう。(今回ググっていろいろ実験するもうまくいかず。また時間がある時に調べよう。)

  • プログラミングとは関係ないけれど、仕事で相手の進捗管理をすることは、コミニケーションにおいて大事だなと今日感じた。特に、うまく行っていなさそうな時、心がおれそうな時、詰まっていそうな時に、進捗を聞いて、自分が5分以内でできそうな部分はアドバイスしたり、話を聞いたりすると、相手の解決への糸口や、モチベーションに繋がっている気がした。(そのことを今日職場の4人にしたら、悩みを抱えていそうな顔が晴れやかになっていたことと、「ありがとう」と言ってもらえて自分自身も嬉しかったため。)

20201008_アウトプット(レスポンシブデザイン・条件分岐・繰り返し処理・yield)

アプトプット画像

今日学んだこと

レスポンシブWebデザイン
  • メディアクエリとは、表示された画面の幅に応じて、適応するスタイルを切り替える機能のこと

  • ブレークポイントとは、メディアクエリで指定していたスタイル適用の分岐点のこと(パソコン・タブレットスマホに適用したデザインを作るためには、2箇所必要)

条件分岐

  • 「case文」を使うと、複数の条件を指定する時に「if文」のelsifを重ねるよりもシンプルにコードを書くことができる。
country = "Japan"

case country
when "Japan"
 puts "こんにちは"
when "America"
 puts "Hello"
when "France"
 puts "Bonjour"
when "China"
 puts "你好"
when "Italy"
 puts "Buon giorno"
when "Germany"
 puts "Guten Tag"
else
 puts "..."
end

繰り返し処理

  • while文を使うと、指定した条件が真である間、処理をループできる。
number = 0

while number <= 5
 puts number
 number += 1
end

# ターミナル出力結果
# 0
# 1
# 2
# 3
# 4
# 5
  • その際、無限ループに注意。コンピュータに大きな負荷をかけるため。

  • 無限ループを止めるものとして「break」を使う。

ブロック

  • ブロックには「do...end」と「{ }」を用いた2つの書き方がある。
ages = [20, 56, 32]

# do...endを用いた形
ages.each do |age|
 puts age
end

# {}を用いた形
ages.each {|age| puts age}
  • yieldとはメソッドに渡されたブロックを実行するための命令である。

  • メソッドの引数としてブロックを明示的に受け取る場合には、引数名の前に「&」をつける。

  • 引数として受け取ったブロックは「callメソッド」で実行できる。

def greeting(&block)
 puts "Hello"
 block.call("Goodbye")
end

greeting do |text|
 puts text
end

# ターミナル出力結果
# Hello
# Goodbye

クラス

  • クラスを継承すると、親クラスから子クラスへ「親のインスタンス変数」と「親のインスタンス変数」が引き継がれる。

  • オーバーライドとは、親クラスのメソッドを子クラスに同名のメソッドを定義することによって上書きすること。




積み残し(復習したいところ)

  • devise rollback方法

  • カラム追加の方法

  • Rails勉強会




感想

  • 今日、仕事でAPIに関するメールが来ていて、今までだったら内容を理解できなかったが、パラムスや、キー、HTTPメソッドの指定など、理解できる部分も多く、成長を感じて嬉しかった。

  • 今日から勉強時間を朝に変更してみた。睡眠の質をアップルウォッチで計測しているが、朝活の時の方が(夜早く寝ている方が)睡眠の質が良かった。明日も試してみる。

20201006_アウトプット

アプトプット画像

学んだこと(モデルのテストコード)

最後に出てくる練習問題を解いた。以下は、出てこなかったところ。

  • テストコードの結果をターミナル上で可視化するための設定を行う
【.rspecのファイル】
--format documentation #追記する
  • (テストではなく本物の) モデルに応じて、テストコードのモデルにもアソシエーションを加える

  • テストコード用の画像は、「publicディレクトリ内>imagesディレクトリを作成」その中に保存する。

  • 文章のダミー作成は「Lorem.sentence」を使うことと、ファクトリーボット内でダミー画像生成を行うには「attach」メソッドを使う。

FactoryBot.define do
  factory :post do
    title {Faker::Lorem.sentence}
    content {Faker::Lorem.sentence}
    association :user

    after(:build) do |post|
      post.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')
    end
  end
end
  • 文章・画像投稿アプリにおける、「Postモデル」のexampleには、「紐づくユーザーが存在しないと保存できないこと」も必要。
it '紐づくユーザーが存在しないと保存できないこと' do
      @post.user = nil
      @post.valid?
      expect(@post.errors.full_messages).to include("User must exist")
    end



積み残し(復習したいところ)

  • devise rollback方法

  • カラム追加の方法

  • Rails勉強会



感想

  • 仕事で疲れていたため「1時間だけやろう」と思って取り組み始めたところ、意外と時間が経っていて、結果2時間取り組むことができた。

  • ”週で”35時間以上という目標を決めたことで、先週に比べて心の余裕がある。

  • セルフコンパッション(自分への思いやり)のスキルを高めたい。

  • そのために、毎日・一週間・一ヶ月という周期ごとのセルフケア(ストレス解消法)を行って、疲れがたまらない様に対策をしたいが「毎日」だけ、思い付かず(笑)
    瞑想や読書かなあ。もう少し考えようと思った。あと、この間のアプリ発表会で行っていたポジティブ日記が素敵だったので今日からやってみよう。

20201005_アウトプット・今週の振り返り

アプトプット画像

今日学んだこと

binding.pryとrails cの違い


「メッセージ」に「チャットルーム」のidがきちんと紐付けされているか、確認したい時に以下のような違いがある。
今回は、rspecを導入し、FactoryBotで生成されたダミーの中身を確認したい。

【binding.pry】実際の処理を止めて動作や中身を確認できる

確認したい直前に、binding.pryをVSコード上に書く。

# 対象ファイルの実行
〇〇@〇〇noMacBook-Air chat-app % bundle exec rspec spec/models/message_spec.rb

# message_spec.rb内にて、定義していた変数を指定
[1] pry(#<RSpec::ExampleGroups::Message::Create>)> @message

# @messageの中身を確認することができる
=> #<Message:0x00007ff9317016d8
 id: nil,
 content: "Corrupti pariatur veniam ratione.",
 room_id: nil,
 user_id: nil,
 created_at: nil,
 updated_at: nil>
rails c(console)】外から、新しい情報を加えたり、処理することができる
# 立ち上げ
〇〇@〇〇noMacBook-Air chat-app % rails c
Running via Spring preloader in process 68296
Loading development environment (Rails 6.0.3.3)

# 外から作るので、createしないといけない
[1] pry(main)> FactoryBot.create(:message)

# 作ったものを、変数の中に入れる
[2] pry(main)> test = FactoryBot.create(:message)

# 変数の中身を取り出す 
[3] pry(main)> test.room.id

# @messageの中身を見ることができる
=> 13



rails全般

  • どんどん中の箱を開けていく時→ドット(.)を使って深堀する

  • 別のものとの繋がりを持たせる時→コンマ(,)を使って繋げる

  • パラムスが絡む時→キーとバリューで表現する→シンボル(:)を使って表す。(引数で渡すときは()が多い。配列から取り出すときは[]が多い。)



テストコードについて

  • モデルのテストコードと、結合テストコードについて学んだ。



積み残し(復習したいところ)

ピンポイントでわからないところは、昨日メンターさんに聞けたので無し。復習したいところをまとめておく。

  • devise rollback方法

  • カラム追加の方法

  • Rails勉強会



今週の振り返り

現在の戦略

  • (HOWよりも)WHYを大事にする

  • 作業時間を確保する(平日4時間、休日10時間)

  • 優先順位を決めて行う(約60%がテックキャンプのカリキュラムを進めること・仲間とのアウトプット、約20%がプロゲートで知識補う、約20%がブログでアウトプット)

達成具合

7日中、3日達成できた(合計36時間行ったものの、平日4時間と休日10時間のハードルを越せなかった。)

今週の振り返り(優先順位)

  • 初めはカリキュラム中心に進めていたものの、MVCの理解が足りないため、分からなかった。

  • このまま進めていても、このカリキュラムの内容が無駄になってしまう気がしたため、遠回りは近道だと信じて、一旦プロゲート中心に復習をした。

  • 遅れてしまったものの、MVCの理解が深まったおかげで、RailsRubyの繋がりがやっと持てて楽しくなった。(WHYをずっと考えていると、後から急に繋がってくる!!)

  • 週の後半からは、カリキュラムの巻き返しを行った。


今週の振り返り(作業時間)

  • 作業時間確保は、理解を深めるにあたって大事だが、時間を超えるまで頑張ろうとしてしまい、睡眠時間が足りなかった(結果、集中力は落ちている気がする)

  • 勉強時間と、睡眠時間の質は両方とも大事なので、方針を少し見直そうと思った。



来週から(戦略の改善)

  • (HOWよりも)WHYを大事にする

  • 作業時間を確保する(原則、平日4時間、休日10時間)
    ただし、 睡眠時間の0時〜6時を守ること。週35時間以上の勉強時間を確保できれば良しとする。

  • 優先順位を決めて行う(約60%がテックキャンプのカリキュラムを進めること・仲間とのアウトプット、約20%がプロゲートで知識補う、約20%がブログでアウトプット)

その他(チームミーティング)

今週のチームミーティングは、ざっくり言うと「自分でポジティブなルールを作り出せたら最強」という話でした。
本当にその通りだなと思ったので、取り入れていこうと思います。

方法

(1)今週あったポジティブなことを書き出す
(2)他の人の発表との、共通点を見つけ出す(つまり、ポジティブの本質は何なのか。)
(3)共通点を元に、それを偶発的ではなく、計画的に作り出せる方法を考える



自分に置き換えてみた

(1)今週あったポジティブな出来事
  • 仕事で大きいミスが発覚したが、テックキャンプでの思考が活きて「現状の把握」をしっかり行った上で「仮説」を立てながら、一つ一つ確認や調整を行ったところ、解決に向かう見通しが立った。「迅速に対応出来ていて素晴らしいね」とまさかの上司からお褒めの言葉をもらえて嬉しかった。この件を通して、新しいことを学んで成長の糧になっていること。

  • MVCの意味がやっとわかって嬉しかったこと。

  • ローラの筋トレをやったこと。(キツイけど終わるとすっきりする)

  • コロナの講演会が大変勉強になったこと。(対策のアップデートしていなかったことに気が付く)

  • メンターさんに褒めてもらえて嬉しかったこと。

  • 別のチームの方で、気が置けない仲間ができたこと。

  • ビードリルやっと追いついたこと(笑)

  • 職場の別のグループの先輩が、私のことを心配してランチに誘ってくれたこと。(とても癒された)

(2)他の人の発表との、共通点を見つけ出す(つまり、ポジティブの本質は何なのか。)
  • 起きた「事実」に対して、どう捉えるかは自分次第。(それなら、ポジティブな主観の方が楽しい)

  • 一人ではなく、誰かとの繋がりがもたらしている。

  • 好きなことや、楽しみなことがそのまま、ポジティブに繋がっている。

(3)共通点を元に、それを偶発的ではなく、計画的に作り出せる方法を考える
  • アインシュタインの「どうして自分を責めるんですか?他人がちゃんと必要なときに責めてくれるんだから、いいじゃないですか。」という言葉を大事にする。(思考を変える)

  • 誰かとの繋がりを持つ時に、感謝の念を持つ。小さなことでも、良いところに目を向ける。

  • ご褒美DAYを作る(戦略を達成できたら、週に1回くらいのペースでぶどうを食べることと、2週間に1回くらいのペースで夫と映画を見る)

以上です。 見ていただいた方、ありがとうございました。

20201004_アウトプット

アプトプット画像

今日学んだこと(チャットアップのメッセージ投稿機能の実装)


form_withについてやっと意味がわかった!!!

  • form_with自体、Rails5.1から追加されたメソッド。それまでは、データを保存する場合には「form_for」を、保存する必要がない時は、「form_tag」を使い分ける必要があった。

  • form_withになってからは、引数の書き方を変えるだけでどちらの意味も、同じメソッドで記述できるようになった。具体的には、データを保存する場合には、「model指定」を、データを保存する必要がない場合には「url指定」を行う。

  • 「url指定」では、リクエストを送信するパスとHTTPメソッドを指定する。(HTTPメソッドの初期値は「:post」、その場合には省略可能。)

<%= form_with url:"/posts", method: :post, local: true do |form| %>
↑
フォームの内容をここに記載
↓
<% end %>



  • 「model指定」は、コントローラーと密接に関わっている。コントローラーにおいてモデルを使ってインスタンスの生成を行うと思うが(例:@tweet = Tweet.new)そこを拾って、何も情報を持っていなければcreateアクションへ、すでに情報を持っている場合にはupdateアクションへ自動的に振り分けてくれる。

  • ビューのform_withで使うためにも、モデルから作成したデータは、インスタンス変数に代入する必要がある。

<%= form_with model: モデルクラスのインスタンス do |form| %>
  • また、コントローラーがネストしている時には、パラムスが絡むため[ ]となる。
<%= form_with model: [@article, @comment] do |form| %>
  • そのほかのform_withでわからなかった所は、「class」は単純にクラス名を指定していることと、「local:true」はHTMLとしてフォームを送信する際に指定が必要となるものだったこと(「local:true」を入れないと、デフォルトではAjaxによる送信となる。アプリケーションによって、このオプションをつけるかどうか使い分ける。)


deviseのマイグレーションファイルの「null: false, default: ""」について

  • deviseでマイグレーションファイルを作成した時に、「default: ""」と入るが、「空で保存できない」のに「デフォルトで余白作らない」って矛盾してる?なぜ?と意味がわからなかった。
t.string :name, null: false
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
  • 結論は「devise」に聞かないとわからないだった。(メンターさんに聞いても意図不明だった。)

  • 自分で後から追加した「name」には「default:""」がなくても平気なので、同じようになくても問題ないが、デフォルトで作成される「email」「password」のマイグレーションファイルは、(その2項目を使うのであれば)いじらないのが原則なのでそのままにする。

  • 個人的な予測としては、空欄では保存できないことと、予期せぬ余白を入れたまま登録を防ぐ意味があるのかなと思った。


CSSでブロック要素が崩れた時の今回の解決法(探し方が勉強になった)

(1)要素が崩れている場合には「divタグが多い・少ない」を疑う。(その際に、対象の部分テンプレートだけでなく、左上の要素から読み込まれるので、そちらも疑う。)

(2)このdivのせいではないか?と思った時に、そのカタマリをいったん消して、ビューで見てみて、原因なのか探るのもあり。



DBの情報をビューに反映させる方法

(1)form_with(modelオプション)でデータを保存

(2)データを表示されるビュー(部分テンプレート)を作成(その際、今回は指定したインスタンス変数の中にある要素の数だけ、部分テンプレートが繰り返し表示されるrenderメソッドのオプションである「collectionオプションを使用」)

<%= render partial: 'hoge', collection: 繰り返し表示する要素が入っているインスタンス %>



データの投稿時間を日本時間に直す方法

(1)config>application.rbを編集

#追加する
    config.i18n.default_locale = :ja
    config.time_zone = 'Tokyo'


(2)config>locales>ja.ymlを編集

ja:
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"


(3)ビュー側で、l(エル)メソッドという日付や時刻を表示するRailsのメソッドを指定する。

<div class="message-date">
      <!-- 投稿した時刻を出力する -->
      <%= l message.created_at %>
    </div>


(4)サーバーを再起動すれば反映される。

その他

  • dependentオプションを使うと、親モデルを削除した時、関連しているモデルの挙動をどうするか指定できる。

積み残し(わからないところ)

  • <%= form_with(model: @tweet, local: true) do |form| %>※モデル →解決!

deviseに関するマイグレーションファイルは書き方がビューに影響する?(名前、Eメール、パスワードがあったとして、ユーザーに入力してもらいたい順番で書かないと順番異なるのか?) →解決! (結果)マイグレーションの書いた順は、 シークエルプロのカラム順に影響。ビューへの影響は、シンプルにビューファイルでどのように書くかだった。



感想

  • ずっとモヤモヤしていたform_withについてすっきりしたので嬉しかった!!

  • 早くカリキュラムを進めて、自分でアプリケーション作った上で、さらに理解を深めたい。

  • アマプラで「インターステラー」を観た。SFっぽいのに現実的で、面白かった!!!(物理学について、毛嫌いしていたけれど、もっと知りたいと思えるほど、わかりやすくて引き込まれる映画だった!アインシュタインの考えがわかるような本読みたい。)

  • 8/1以降、軽く散歩などには出かけるものの、土日の時間についてずっとプログラミングに費やしていた。たまには、リフレッシュできるので、ご褒美に映画もいいなと思った。

20200930_アウトプット(devise関連)

アプトプット画像

学んだこと

deviseを用いたユーザーの管理機能について学んだ。


サインアップ/ログイン機能

【1】ログインしていない場合に、ログイン画面に遷移するように実装する。
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
end
  • authenticate_user!メソッドを使用する。

  • authenticate(読:オセンティケイトゥ 意:認証する)

  • ビフォーアクションに定義することで、他のアクションが読み込まれる前に、ログイン画面へ遷移させることができる。




【2】ユーザーの名前をDBへ保存できるように設定する。
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
  • Rails では、セキュリティ対策のため、保存のルールを予め決めておかないと保存できない仕組みになっている。deviseにおいて、emailやpasswordはデフォルトで作成されるが、nameのように自分で追加したカラムがある場合には、保存するルールを決める。

  • devise_parameter_sanitizerメソッドとは、deviseでユーザー登録をする場合に使用でき、「特定のカラムを許容する」メソッド。

  • 今回の「configure_permitted_parametersメソッド」の内容の意味は、「nameカラム」を追加したので、このメソッドを使用し、「name」キーの内容の保存をpermitメソッドで許可するということ。


ユーザー情報編集機能

#ルーティングの設定
Rails.application.routes.draw do
  devise_for :users
  root to: "messages#index"
  resources :users, only: [:edit, :update]
end


#ターミナルで実行
% rails g controller users


#usersコントローラーの設定
class UsersController < ApplicationController

  def edit
  end

  def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
【1】ユーザー情報編集画面が表示されるように設定する。
  • 「devise_for :users」により、基本的なルーティングは設定しなくても遷移されるが、今回のようなユーザーの編集画面を作るには「:edit」と「:update」を追加する必要がある。

  • ルーティングを設定したら、コントローラーを作成する。



【2】ユーザー情報が更新されるように実装する。
  • Userモデルの更新を行うupdateアクションをusersコントローラーに定義する。

  • ストロングパラメーターを使用し、user_paramsを定義する。

  • user_paramsの中でpermitメソッドを使用し、「name」と「email」の編集を許可する。

  • ユーザー情報が格納されているcurrent_userメソッドを使用して、ログインしているユーザーの情報を更新する。



【3】更新が成功するとチャット画面に遷移して、失敗するとeditページに戻ってくるように実装する。
  • updateアクション内で、保存できた場合とできなかった場合で条件分岐の処理を行う。

  • current_user.updateに成功した場合、root(チャット画面)にリダイレクトする。

  • 失敗した場合、render :editとeditのアクションを指定しているため、editのビューが表示される。

renderとredirect_toの違いって?
  • renderとは、呼び出すビューを指定するメソッド。(コントローラーとビュー、どちらでも使用可。)
render redirect_to
新たにリクエストされることなくそのままビューを表示する(レンダーからビューへ) 新たなリクエストを送信されたときと同じ動きをする(リダイレクトから、ルーティング・コントローラーを経由してビューへ)
元のインスタンス変数の値は上書きされない(今回=フォームに入力した内容を保持したままユーザー編集画面に戻る) 元のインスタンス変数の値は上書きされる




ログアウト機能

【1】ログアウトできるようにビューにリンク先の設定を行う。
#app/views/users/edit.html.erb内
<%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: 'btn'%>
  • rails routes」コマンドにて、ログアウトに関するパスを探す。

  • ポイントとして、基本的なdeviseに関するルーティングは、元々備わっているため(今回で言えばsessionsコントローラーのdestroyアクション)ルーティングにおいて「destroy」を定義しなくても、遷移する。(ルーティング内の「devise_for :users」に備わっている。)

バリデーション機能

【1】モデルにバリデーション機能をつける。
#app/models/user.rb内
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  validates :name, presence: true

end
  • 空の場合はDBに保存しないというバリデーションを設定した。

  • deviseに対して後付けしたカラムは、自分でバリデーションを設定する必要がある。




積み残し(わからないところ)

  • <%= form_with(model: @tweet, local: true) do |form| %>※モデル

  • deviseに関するマイグレーションファイルは書き方がビューに影響する?(名前、Eメール、パスワードがあったとして、ユーザーに入力してもらいたい順番で書かないと順番異なるのか?)




感想

  • ブログにアウトプットとして書くために、もう一回見返したり考えたりすると、理解していない部分が改めて見つかるので大切だと実感。

  • 最近、パソコン見すぎて、目が乾く。

  • MVCの復習を挟んだことにより、やっと、想像できるようになった。(この機能入れるなら、ルーティング、モデルだろう、という予想)

  • 想像できるものの、実際にコードを書くと、細かい部分まで理解できてないのが悔しい。(例えば、これはアクションだからこう表記する、シンボルだからこう表記するというようなこと。)

  • deviseのアクションなのか、メソッドなのか、やっと理解できた気がする。メソッドに関してはもう一回、おさらいしたいな。