チワワかわいいブログ

RUNTEQでrails勉強する日々の記録

2020/12/30 i18nによる日本語化

やること

rails-i18nと、手動でのファイル作成の2通りで日本語化する。
Ruby on Railsでは、デフォルトの言語設定が英語になっている。
configファイルの設定を変更しgem 'rails-i18n'を導入することで、言語設定を日本語に変更する。
また、gem 'rails-i18n'に含まれていない言葉をアプリケーション上で日本語表示にするため、辞書ファイル(ja.yml)を作成し読み込ませる。

configファイルの設定を変更する

config/application.rbに以下を追記。(アプリケーション全体の設定なのでこのファイル)

config.i18n.default_locale = :ja
gem 'rails-i18n'をインストールする

gemファイルに以下を追記し、bundle install

gem 'rails-i18n'

このgemを入れるとここに含まれるものは日本語に設定される。
早速実験

irb(main):002:0> user = User.new(last_name: "ryutaro")
=> #<User id: nil, email: nil, crypted_password: nil, salt: nil, last_name: "ryutaro", first_name: nil, created_at: nil, updated_at: nil>
irb(main):003:0> user.save
   (0.1ms)  begin transaction
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" IS NULL LIMIT ?  [["LIMIT", 1]]
   (0.0ms)  rollback transaction
=> false
irb(main):004:0> user.errors
=> #<ActiveModel::Errors:0x00007fb8fb854038 @base=#<User id: nil, email: nil, crypted_password: nil, salt: nil, last_name: "ryutaro", first_name: nil, created_at: nil, updated_at: nil>, @messages={:password=><span style="color: #ff5252">["は3文字以上で入力してください"]</span>, :password_confirmation=>["を入力してください"], :first_name=>["を入力してください"], :email=>["を入力してください"]}, @details={:password=>[{:error=>:too_short, :count=>3}], :password_confirmation=>[{:error=>:blank}], :first_name=>[{:error=>:blank}], :email=>[{:error=>:blank}]}>

日本語になった!

辞書ファイルを作る

ja.ymlファイルをconfig/locales以下に作成する。
今回は、model用、view用に分けて2つ作成。
ja.ymlを作成したフォルダ名を起点に、ディレクトリごとにインテンドを入れて記述する。

ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
      user: #インテンド一個下げる
        id: ID
        first_name: 名
        last_name: 姓
        email: メールアドレス
        crypted_password: パスワード
        password: パスワード
        password_confirmation: パスワード(確認用)
  attributes:
    created_at: 作成日
    updated_at: 更新日
configファイルの設定を変更する②

ja.ymlファイルが複数あるため、読み込みできるように設定を追記

config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
設定を反映する
viewの場合
<%= link_to t('login'), login_path %>

上位フォルダがある場合は
t('users.index.login')のように記載

<%= f.label :email, t('activerecord.attributes.user.email') %>

フォームのmodelに@userなどモデルのインスタンスを渡している場合
<%= f.label :email %>

モデルで使う場合

モデル名.human_attribute_name(:カラム名)

ActiveRecordのメソッドで、モデルごとに指定した属性名を取得できる。
モデル名と属性名を参照元を明示して国際化対応できるため、こちらで記述を行う方がいい。

2020/12/29 sorcery

やったこと

form_with

ラベルタグを以下のように書いていたら

<%= f.label "First name" %>
<%= f.text_field :first_name, class: "form-control" %>

ブラウザでラベルをクリックしても入力フォームにカーソルが移動しない

<%= f.label :first_name, "First name" %>
<%= f.text_field :first_name, class: "form-control" %>

第一引数にカラム名を入れ忘れていたことで、正しく関連づけられていなかった
と思ったけど、

<%= f.label "first_name" %>

と書き直してもラベルのクリックでフォームに移動した
labelとtext_fieldの引数が違ったから反応しなかったと理解

sorcery

盛りだくさんで頭いっぱいになる
インストールすることで使えるようになるメソッドを確認

  • login
@user = login(params[:email], params[:password])

のように使う。
emailによるUser検索、パスワードの検証を行い、正常に処理できるとセッションデータにUserレコードの id値を格納する。

  • logged_in?
    現在ログイン中かtrue/falseで返す

  • redirect_back_or_to
    ログイン前にアクセスしようとしたURLがあればそこにリダイレクト、なければ指定のURLに返す

  • logout
    セッション情報を削除してログアウトする

  • require_login
    ログインしていないユーザーに対しnot_authenticatedアクションを実行する
    また、ここでアクセスしようとしたURLをセッションに格納しているため上述のredirect_back_or_toが使える
    before_actionにしてログイン必要なページで弾くことができるが、staticpagesコントローラにスキップの記載忘れててトップページが開けず詰まった

    リテラル記法

    Rubocopでのチェック

Use %i or %I for an array of symbols.

%記法を使えとのこと。
参考: shinmedia20.com
%記法のメリット→タイプ数が減る、可読性が増す

カラムにnull制約をたす

モデルのvalidationで設定した項目は、同じ制約をデータベースにも設定する必要がある
データベースにも制約をつけないと、モデルを通さず直接データ操作したときに不整合なデータができる可能性があり、不具合やエラーの原因となりかねないとのこと。 手順を確認。

rails generate migration add_null_false_to_users

#migration
  def change
    change_column_null :users, :last_name, null: false
    change_column_null :users, :first_name, null: false
  end

change_column_null :users, :last_name, null: false, 0
のように、第4引数を指定した場合はDBにすでにnullの項目があった場合に指定した引数に置き換えてくれる。(今回は割愛)
第4引数は既存のものを変更するだけで、デフォルト値を設定するわけではないので、デフォルト値も設定したい場合は以下のように同時に変更を加える必要がある

  def change
    change_column_null :users, :last_name, null: false, 0
    change_column :users, :first_name, :integer, default: 0
  end
form_withのオプション

基本的にはmodel:を使う
次のようの場合はurl:を使う

  • モデルとフォームが紐づかない場合(例: ログインフォーム: user_sessions)
  • createやupdateを行うコントローラがモデルと単純に紐づかない場合
    (例: model: @userと設定したが、members_controllerに処理が遷移して欲しい場合)

保存に失敗した時に、入力フォームに値が残っている流れ

  1. createアクションで@userの保存に失敗(→DBへの保存は失敗しているが、ユーザー情報は残っている)

  2. render :newで再度表示された時に、1の@userがviewに渡される

  3. form_with model: @user の記述により、@userに入っている情報がテキストフィールドに表示される

2020/12/27 基礎課題2,3

  • application.scssではrequire_tree(同じディレクトリにあるscssファイルを全て読み込み)ではなく、@import 'top';のように個別に読み込む → ファイルの読み込む順番がわからなくなってしまうのを防ぐ
  • bundlerを使うメリット bundlerを使うと、gemfileのライブラリ同士のバージョンや依存関係をエラーが出ないように管理してくれる
    bootstrapの導入
  • gemfileに以下を追加
gem 'bootstrap', '~> 4.4.1'
gem 'font-awesome-sass', '~> 5.12.0'
gem 'jquery-rails'
  • application.scssに以下を追加
@import 'bootstrap';
@import 'font-awesome-sprockets';
@import 'font-awesome';
  • jsファイルを変更、/app/assets/javascripts/application.js
//= require jquery3 
//= require popper 
//= require bootstrap-sprockets

バージョン指定はrubygemsで調べる
scssファイルには*= requireなどのSprocketsディレクティブの記載が残っていると、@importで定義した内容がうまく読み込めずbootstrapが反映されない

socery

gem soceryをインストールする
この辺の色々なメソッドを使えるようになる

# Gemfile
gem 'sorcery'

rails g sorcery:install →この時点で自動でusers modelができる 

class User < ApplicationRecord
  authenticates_with_sorcery!  →モデルに最初からメソッドがある
end

2020/12/26 基礎課題1

環境構築から始める
rubyのバージョンがインストールされていないとなるので、rbenv install 2.6.4でインストールして続行

bundle install --path vendor/bundle

--path vendor/bundle オプションとは
--プロジェクトのディレクトリ配下にある、vendor/bundle配下にgemをインストールするように指定するオプションです。
なぜ --path vendor/bundle オプションをつけた方が良いか
--path vendor/bundle オプションをつけ、ローカルではなくプロジェクト内にインストールすることで、
ローカルに複数バージョンのgemがインストールされてごちゃごちゃになってしまうことを防げます。
参考:

bunle install するときの --path vendor/bundle オプション - haayaaa’s diary

bundle exec rails db:setup

と指示があるので、execって何か調べる
参考:

qiita.com

今回は、rails generate実行時に不要なファイルが作成されないようにする設定

config/initializers以下の各ファイル 特定のツールや機能に対する設定ファイルを、ファイル別に記述する。(assets.rb / aws.rbなど)

config/environments以下 環境別に行いたい初期化作業を記述する (production.rb / staging.rb など)

config/applicaiton.rb アプリケーション全体に関する設定を行う

今回は、/config/application.rb に記述する。

    config.generators do |g| →今回は複数なのでブロックにしているが、config.generators.assets falseのように記述も可能
      g.resource_route  false → 回答はg.skip_routes true
      g.test_framework  false
      g.assets          false
      g.helper          false
    end


残った疑問
* bundle exec

2020/12/24 テスト復習

間違えた問題

railsにあるファイルの役割
  • db/schema.rb データベースのスキーマ情報が書いてあるもの。
  • db/seed/rb データベースに初期データを作成する記述をするもの。
  • config/application.rb
    Railsアプリケーション全体の設定を行う。タイムゾーンや国際化など。
  • config/database/yml
    利用するデータベースの設定を書くもの。
    • どのデータベースを利用するか(SQLite3/Psotgresql, Mysqlとか)
    • データベースのログイン情報
paramsからの代入

strong_parameterの理解不足。あとprogateで使ってたform forに引っ張られてしまった。

名前付きルートのURL確認

app.user_pathとかコンソールでやると出てくる!

render

そういえばそうだったかも・・

<% User.all.each do |u| %>
  <%= render 'user', user: u %>
<% end %>

を簡略して書いたのが

<%= render User.all %>

なので、renderするテンプレートは_user.html.erbになる

resource

「実はresourcesとは別にresourceという「単一リソース」を表現するものがある」
複数のリソース(userとかmicropost)とかに対応するroutesを作成→resources
単一のリソースに対応するroutesを作成→resource

scope

モデル名.スコープ名("引数")の構文

    # deletedカラムがfalseであるものを取得する
    scope :active, -> { where(deleted: false) }
    # created_atカラムを降順で取得する
    scope :sorted, -> { order(created_at: :desc) }
    # activeとsortedを合わせたもの
    scope :recent, -> { active.sorted }

データベースのクエリをまとめるためのメソッド。
チュートリアルで正直ほぼ読み飛ばしてた。。よく使いそうなのでしっかり覚える

2020/12/23 補講課題

ようやくrailsチュートリアル一周したので、RUNTEQのチェックテスト前の補講課題
コマンド実行して環境構築

$ git checkout -b fix_[自分のアカウント名] #作業ブランチ作る
$ rbenv local 2.6.6 #rubyのバージョンを指定
$ nodenv local 12.14.0 Node.jsのバージョンを指定 サーバサイドでJavaScript動かすらしいけど何ができるのか全然わからない
$ bundle install --without production 
$ yarn install #javascriptのパッケージマネージャ,ライブラリの追加やインストールを容易にしてくれるやつ
$ rails db:migrate
$ rails server

最初からエラーが出る、やだ

An error occurred while installing puma (4.3.3), and Bundler cannot
continue.
Make sure that `gem install puma -v '4.3.3' --source 'https://rubygems.org/'`
succeeds before bundling.

以下のコードでいけるとのことでまんまやってみた

$ gem install puma:4.3.3 -- --with-cflags="-Wno-error=implicit-function-declaration"

これを参考

【puma】puma4台インストールできない問題の対処法 - Qiita
rails severでもエラーでた

========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================

To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).

書かれてる通りwebpacker.ymlを変更したら大丈夫だった
パッケージが古くなっていたらエラーになってパッケージを最新の状態に保つ手助けになるオプションとのこと
晴れてserverも立ち上がったので、とりあえず最初のテスト
安川先生がいなくて不安・・ とりあえずエラーを書き出してみる

Error:
UserTest#test_success_to_visit_about_page:
NameError: undefined local variable or method `about_url' for #<UserTest:0x00007fd0ada5dd60>
    test/system/user_test.rb:49:in `block in <class:UserTest>'

Error:
UserTest#test_login_failed_with_not_exist_user:
NoMethodError: undefined method `authenticate' for nil:NilClass
    app/controllers/sessions_controller.rb:6:in `create'

Error:
UserTest#test_logout_success:
NoMethodError: undefined method `log_in' for #<SessionsController:0x00007fd09899f5c8>
Did you mean?  login_url
Did you mean?  login_url
    app/controllers/sessions_controller.rb:7:in `create'

Error:
UserTest#test_login_success_with_exist_user:
NoMethodError: undefined method `log_in' for #<SessionsController:0x00007fd0c81e8ae8>
Did you mean?  login_url
Did you mean?  login_url
    app/controllers/sessions_controller.rb:7:in `create'

Failure:
UserTest#test_signup_success_with_valid_user [/Users/workplace/runteq/Exam_RailsBasic_01/test/system/user_test.rb:37]:
expected to find text "Signup success!" in "RUNTEQ APP\nLog in\nSign up\nThe form contains 3 errors.\nPassword can't be blank\nPassword is too short (minimum is 6 characters)\nPassword can't be blank\nName\nEmail\nPassword\nConfirmation"

テスト一個ずつ見ていく

  test "success to visit about page" do
    visit about_url
    assert_text "StaticPages#about"
  end

routes.rbを修正して、コントローラにアクション追加して、about.rbのファイル名修正したんだけどこれでいいのか?
もう一回テストしたらエラーメッセージ異常になったけど一旦無視

  test "login failed with not exist user" do
    visit login_url
    fill_in "Email", with: "other_user@example.com"
    fill_in "Password", with: "foobar"
    click_button "Log in"
    assert_no_text "Example User"
  end

これはnilガードっぽいのでsessionsコントローラのcreateアクションを修正

  test "logout success" do
    login
    click_on "Account"
    click_on "Log out"
    assert_text "Log in"
  end

log_inメソッドがあるsessionhelperをincludeしてみる

  test "signup success with valid user" do
    visit signup_url
    fill_in "Name", with: "Another User"
    fill_in "Email", with: "another_user@example.com"
    fill_in "Password", with: "foobar"
    fill_in "Confirmation", with: "foobar"
    click_button "Create my account"
    assert_text "Signup success!"
    assert_text "Another User"
  end

最後のはvalidation、userコントローラのcreateアクション、singupのテンプレートあたりがおかしそう
と思ったらstrong_parameterにpasswordがなかった
修正したけど、エラー出る
userコントローラでもlog_inメソッド使いたいとのことなので、includeをapplicationcontrollerに描き直し
で終わり!

解説動画

眠いけど1時間頑張って見る!

  • git hub 右上からclone用のURLが入手できる
  • mkdir -pでないフォルダとかも作成される、前も出てきたけどコマンドすぐ忘れてしまう
  • ブラウザの検証ツール ネットワークタブでなんのデータを送ったかとかが見れる!便利そう
  • binding.irbをアクションの中に組み込むと、そこで止まる serverを立ち上げているターミナルでその時点のフォームの情報とかが確認できる
    ここでuser = User.new(user_params)すると、エラーに引っかかる原因を割り出せるかも
    さっき大分目視で見つけたから、こういうやり方覚えていきたい
  • command + shift + F、grep -r 文字列 で検索できる!
    さっきは普通に探し回った
  • findはエラーを返す、find_byはnilを返す
  • ぼっち演算子 user&.autenticate(params[....)慣れない
  • def new; end など1行で書くとデフォルトのテンプレート表示するだけのメソッドってことでOKですよ、ということを明示できる
  • ターミナルでhistoryコマンド → ctrl + R で使ったコマンドの履歴が出せる、検索できる
  • better errors (gem)
  • ps 今動いているプロセスを確認→killコマンドで停止

2020/12/22 補講課題

ようやくrailsチュートリアル一周したので、RUNTEQのチェックテスト前の補講課題
コマンド実行して環境構築

$ git checkout -b fix_[自分のアカウント名] #作業ブランチ作る
$ rbenv local 2.6.6 #rubyのバージョンを指定
$ nodenv local 12.14.0 Node.jsのバージョンを指定 サーバサイドでJavaScript動かすらしいけど何ができるのか全然わからない
$ bundle install --without production 
$ yarn install #javascriptのパッケージマネージャ,ライブラリの追加やインストールを容易にしてくれるやつ
$ rails db:migrate
$ rails server

最初からエラーが出る、やだ

An error occurred while installing puma (4.3.3), and Bundler cannot
continue.
Make sure that `gem install puma -v '4.3.3' --source 'https://rubygems.org/'`
succeeds before bundling.

以下のコードでいけるとのことでまんまやってみた

$ gem install puma:4.3.3 -- --with-cflags="-Wno-error=implicit-function-declaration"

これを参考

【puma】puma4台インストールできない問題の対処法 - Qiita
rails severでもエラーでた

========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================

To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).

書かれてる通りwebpacker.ymlを変更したら大丈夫だった
パッケージが古くなっていたらエラーになってパッケージを最新の状態に保つ手助けになるオプションとのこと
晴れてserverも立ち上がったので、とりあえず最初のテスト
安川先生がいなくて不安・・ とりあえずエラーを書き出してみる

Error:
UserTest#test_success_to_visit_about_page:
NameError: undefined local variable or method `about_url' for #<UserTest:0x00007fd0ada5dd60>
    test/system/user_test.rb:49:in `block in <class:UserTest>'

Error:
UserTest#test_login_failed_with_not_exist_user:
NoMethodError: undefined method `authenticate' for nil:NilClass
    app/controllers/sessions_controller.rb:6:in `create'

Error:
UserTest#test_logout_success:
NoMethodError: undefined method `log_in' for #<SessionsController:0x00007fd09899f5c8>
Did you mean?  login_url
Did you mean?  login_url
    app/controllers/sessions_controller.rb:7:in `create'

Error:
UserTest#test_login_success_with_exist_user:
NoMethodError: undefined method `log_in' for #<SessionsController:0x00007fd0c81e8ae8>
Did you mean?  login_url
Did you mean?  login_url
    app/controllers/sessions_controller.rb:7:in `create'

Failure:
UserTest#test_signup_success_with_valid_user [/Users/workplace/runteq/Exam_RailsBasic_01/test/system/user_test.rb:37]:
expected to find text "Signup success!" in "RUNTEQ APP\nLog in\nSign up\nThe form contains 3 errors.\nPassword can't be blank\nPassword is too short (minimum is 6 characters)\nPassword can't be blank\nName\nEmail\nPassword\nConfirmation"

テスト一個ずつ見ていく

  test "success to visit about page" do
    visit about_url
    assert_text "StaticPages#about"
  end

routes.rbを修正して、コントローラにアクション追加して、about.rbのファイル名修正したんだけどこれでいいのか?
もう一回テストしたらエラーメッセージ異常になったけど一旦無視

  test "login failed with not exist user" do
    visit login_url
    fill_in "Email", with: "other_user@example.com"
    fill_in "Password", with: "foobar"
    click_button "Log in"
    assert_no_text "Example User"
  end

これはnilガードっぽいのでsessionsコントローラのcreateアクションを修正

  test "logout success" do
    login
    click_on "Account"
    click_on "Log out"
    assert_text "Log in"
  end

log_inメソッドがあるsessionhelperをincludeしてみる

  test "signup success with valid user" do
    visit signup_url
    fill_in "Name", with: "Another User"
    fill_in "Email", with: "another_user@example.com"
    fill_in "Password", with: "foobar"
    fill_in "Confirmation", with: "foobar"
    click_button "Create my account"
    assert_text "Signup success!"
    assert_text "Another User"
  end

最後のはvalidation、userコントローラのcreateアクション、singupのテンプレートあたりがおかしそう
と思ったらstrong_parameterにpasswordがなかった
修正したけど、エラー出る
userコントローラでもlog_inメソッド使いたいとのことなので、includeをapplicationcontrollerに描き直し
で終わり!