20210506のRubyに関する記事は18件です。

Rubyの for式 について

Rubyのfor式について学習しました。 初投稿です。これから上手く伝えられるように頑張ります! forとは繰り返し文の時に使用します。 基本的な書き方 (基本) for 変数 in 範囲 do 処理 end (例) for number in 0..10 do puts number end (結果) 0 1 2 3 4 5 6 7 8 9 10 forで 配列 を扱う (基本) for 変数 in 配列オブジェクト do 処理 end (例) Numbers = ["one","two","three"] for Number in numbers do puts number end (結果) one two three forで ハッシュ を扱う (基本) for 変数1, 変数2 in 配列オブジェクト do 処理 end (例) numbers = {one:"1",two:"2",three:"3"} for english, number in numbers do puts "#{english}は#{number}です" end (結果) oneは1です twoは2です threeは3です
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ユーザ登録機能の実装(deviseを使用して説明)ビュー作成〜

ビューの作成 deviseインストールからuserモデル作成までは下記の記事にて書かせていただきました。 今回はビューの作成を行います。 deviseでログイン機能を実装すると、ログイン/サインアップ画面が自動的に生成されます。 しかし、ビューはファイルは生成されていません。 なので、コマンドでビューファイルを生成します。 ターミナル . rails g devise:views ビューファイルが生成されました。 サインアップのビュー app/views/devise/registrations/new.html.erb ログインのビュー app/views/devise/sessions/new.html.erb コントローラーについて ビューファイルができ、前記事でモデルを作成し、ルーティングの自動で生成される事を確認しました。 残るはコントローラーです。 deviseのコントローラーはGem内に記述されているため、編集することができません。 そのため、applicationコントローラーで記述します。 applicationコントローラーはコントローラー内での頂点です。全てはここから始まります。(言い切ってはいけない) 全てのコントローラーの1行目には下記が記述されています。 controller.rb class HogeController < ApplicationController applicationコントローラーでストロングパラメーターを設定します。 app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birth_day]) end end 1つづつ確認していきます before_action :configure_permitted_parameters, if: :devise_controller? before_actionで全てのコントローラーの前に動き、またif: :devise_contoroller?でdeviseにまつわる事が起きたときに作動します。 private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birth_day]) end end deviseにおけるストロングパラメーターです。deviseの「ログイン」「新規登録」などのリクエストからパラメーターを取得できます。 このメソッドとpermitメソッドを組み合わせることにより、deviseに定義されているストロングパラメーターに対し、追加したカラムも含めることができます。(email,passwordはすでに定義されているため)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Gem パスワードを暗号化するbcyptの使い方

bcyptとは パスワードを暗号化してセキュリティを向上させるためのGemです。 bcyptのインストール Ruby on RailsのGemfileの中にコメント付きで既に記述されていので そのコメントアウトを外してbundle installすることでインストールすることができます。 % bundle install bycypt bycyptでは主に2つのメソッドを使うことができるようになります。 has_secure_passwordメソッド authenticateメソッド ・has_secure_password モデル内に1行書くことにより、passwordとpassword_confirmationという属性を使うことができます。 maigationファイルにカラムを追加する場合はpassword,password_confirmationではなく 20210416072618_add_password_to_users.rb class AddDetailsToTitles < ActiveRecord::Migration def change add_column :users, :password_digest, :string end end とする必要があるので注意です。 passwordを格納するデータベースのテーブルにはpassword_digestというカラムを作成しておくと、 passwordとpassword_confirmationで入力したパスワードが一致していれば password_digestカラムに暗号化してパスワードを格納することができるようになります。 viewファイルにpasswordとpassword_confirmationをフォームで送るだけでbcyptが暗号化してくれます。 _form.erb <%= form_with model: @user do |f| %> <%= f.label :password %> <%= f.password_field :password %> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation %> <% end %> ・authenticateメソッド authenticateメソッドはパスワードを認証するためのメソッドで正しいパスワードを入力するとtrueを返し、間違ったパスワードを入力するとfalseを返します。 パスワードのバリデーションは標準で装備されています。 アプリを作って試してみる % rails new password_app % cd password_app % rails db:create Gemfile # gem 'bcrypt', '~> 3.1.7' を外して % bundle install Userモデルを作成してpassword_digestカラムを作成します。 % rails g model user password_digest:string 作成できたら % rails db:migrate userモデルにhas_secure_passwordを書きます。 models/user.rb class User < ApplicationRecord has_secure_password end rails consoleで動作確認します。 $ rails c 間違ったパスワードを入れるとfalseが返ってきて 正しいパスワードを入れると情報が返ってきています。 irb(main):001:0> u = User.new (1.3ms) SELECT sqlite_version(*) => #<User id: nil, password_digest: nil, created_at: nil, updated_at: nil> irb(main):002:0> u.password = "1234" => "1234" irb(main):003:0> u.save (0.2ms) begin transaction User Create (3.6ms) INSERT INTO "users" ("password_digest", "created_at", "updated_at") VALUES (?, ?, ?) [["password_digest", "$2a$12$PaXO7LLKIqWGIXFhpkZcgOPSv2H.Mrmol6XwvI0aYMxrYdCFlmQCS"], ["created_at", "2021-05-06 13:04:13.549990"], ["updated_at", "2021-05-06 13:04:13.549990"]] (1.6ms) commit transaction => true irb(main):004:0> u.authenticate("3333") => false irb(main):005:0> u.authenticate("1234") => #<User id: 4, password_digest: [FILTERED], created_at: "2021-05-06 13:04:13", updated_at: "2021-05-06 13:04:13"> 以上です。 参考サイト Qiita Railsにおけるパスワードの扱い方(BCrypt) FREE SWORDER Railsアプリのパスワードを暗号化する方法〜bcryptの使い方〜 Rails Tutorial
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby ハッシュの生成方法

hashについて hashは、複数の関係性のある値を管理する際に使うもので、キーとバリューを要素に持つ値です。 配列とは異なり、順番ではなく、キーを使って値を管理する方式のことをキーバリューストアと呼びます。 hashの生成方法 hashの生成方法はハッシュを宣言し、その中にキーとバリューをセットに代入します。 変数 = {} # 始めから要素を持った状態で生成することもできます。 変数 = { "キー1" => "バリュー1", "キー2" => "バリュー2", "キー3" => "バリュー3" } ハッシュのキーには多くの場合、シンボルと呼ばれる文字列の先頭にコロン:をつけて宣言する値が使用されます。 :文字列 文字列よりも、数値を扱うほうが処理速度が早くなるので、ハッシュのキーには、文字列よりもシンボルを使うことが多いようです。シンボルを使うと見た目は文字列ですが、数値として扱われます。 シンボルを使う場合は、以下の2通りの使用方法があります。 hash = { :name => "inoki" } hash = { name: "inoki" } # 2つとも同じ意味 まとめると、ハッシュの生成方法には以下の3つの方法があります。 hash1 = {"name" => "あん時の猪木"} hash2 = {:name => "あん時の猪木"} hash3 = {name: "あん時の猪木"} # 全ておなじ意味 シンボル化を行うメソッド 文字列をシンボル化するには、to_symメソッドを使います。このメソッドを使うことでシンボルオブジェクトを返すことができます。 str = "inoki" str = str.to_sym str.class # Symbol
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on rails でLine push(プッシュ)メッセージ(ブロードキャスト)を送る

概要 LINEAPIでメッセージを送る場合、応答メッセージとプッシュメッセージの大きく2つに分けられます。 応答メッセージはオウム返しのような、ユーザーのアクションに対して応答するタイプで、プッシュメッセージはユーザーのアクションに関係なく、サーバーサイドからプログラムを実行し、メッセージを送れるタイプです。 ネット上の記事を見渡すと応答メッセージに関するLINEボットの記事がたくさんあるのに対し、プッシュメッセージについて書かれた記事があまりなかった印象を受けたのに加えある一定の需要がありそうなので書き残しておきます。 環境 Ruby(2.2以上) Rails(5以上) 今回やりたいこと 公式のドキュメントに書いてあるようにヘッダーにアクセストークン、bodyに送りたい相手のユーザーID(ブロードキャストの場合不要)、メッセージの内容を格納してAPIを叩く(postする)ことでメッセージを送信できます。 このcurlコマンドの内容をRubyで書き換えることが今回のゴールです。 以上のことを踏まえて手順を細分化すると 1. Line Developerで自分のアクセストークンとユーザーIDを取得 2. curlコマンドを叩いてメッセージが自分のアカウントに送信できているか確認 3. Rubyでコードを書く。 4. リファクタリング(出来たら) という流れになります。 一つ一つ見ていきましょう。 1.Line Developerで自分のアクセストークンとユーザーIDを取得 LINE Developerのマイページに書いてあるYour user IDが自分のアクセストークンに該当し Channel Access Tokenがアクセストークンに該当します。 詳しい記事は割愛しますので他の記事や公式ドキュメントをご参照ください。 2.curlコマンドで確認 ブロードキャスト(友達全員に送信)の場合 curl -v -X POST https://api.line.me/v2/bot/message/broadcast \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {channel access token}' \ -d '{ "messages":[ { "type":"text", "text":"Hello, world1" }, { "type":"text", "text":"Hello, world2" } ] }' この該当部分(ヘッダーのアクセストークン)を変更しメッセージが遅れてるか確認。 マルチキャスト(特定の複数ユーザーに送信)の場合 curl -v -X POST https://api.line.me/v2/bot/message/multicast \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {channel access token}' \ -d '{ "to": ["U4af4980629...","U0c229f96c4..."], "messages":[ { "type":"text", "text":"Hello, world1" }, { "type":"text", "text":"Hello, world2" } ] }' この場合は送りたい相手のユーザーIDが必要です。 自分のIDはマイページから確認できますが友達のIDは友だち追加やメッセージの受信をトリガーにIDを取得できるコードを書いて格納するのが一般的です。 その他の送信方法は公式ドキュメントをご参照ください。 3.Rubyで書き換える 実際のコード(ブロードキャスト) message.rb class Message def broad_push require 'net/http' require 'uri' require 'json' token = ENV["LINE_CHANNEL_TOKEN"] # post先のurl uri = URI.parse('https://api.line.me/v2/bot/message/broadcast') http = Net::HTTP.new(uri.host,uri.port) http.use_ssl = true # Header headers = { 'Authorization'=>"Bearer #{token}", 'Content-Type' =>'application/json', 'Accept'=>'application/json' } send_message = #自分が送りたいメッセージ # Body params = {"messages" => [{"type" => "text", "text" => send_message}]} response = http.post(uri.path, params.to_json, headers) end end 今回はブロードキャストで実装しましたが他のマルチキャスト等も流れはほとんど同じで、bodyとurlを変更するだけで実装できます。 今回は環境変数を格納するにあたり.envファイルで管理しています。(githubに間違えてプッシュしないように) Rails環境下でしか使えないのでお気をつけください。 rake taskで定期実行 push_message.rb namespace :push_message do desc "line ブロードキャスト機能で友達全員に明日の予定をプッシュする" task tomorrow_plans: :environment do message = Message.new message.broad_push end end Herokuなどで決まった時刻に定期実行したい場合はrake taskで実行できるようにtaskに切り出しておくと便利です。 今回は rake push_message:tomorrow_plans のコマンドで実行出来ます。 rake taskの解説記事 まとめ 如何でしたでしょうか? 実用的なアプリを作りたい場合プッシュメッセージは案外使うケースが多いと思うので、是非参考にして頂けると幸いです。Lineが提供しているgemを使用して書くことも出来ますがこのようなシンプルにpostするだけなので短い処理であれば使う必要はないと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

migrateしてしまったモデルとテーブルの削除方法

はじめに モデルを作成してマイグレーションしてから、作成されたモデルとテーブルを削除する必要があったので、その時の手順を残しておきます。 削除手順 ①モデル作成時のファイルを削除する。 ②削除用のファイルを新規作成する。 ③削除用のファイルに削除したいテーブルを記載。 ④マイグレーションして、削除を行う。 ①モデル作成時のファイルを削除する。 まず以下を入力して、該当モデル作成時のファイルを削除します。 今回は、クチコミサイト作成時商品にカテゴリを付与したいと考えたので、categoryモデルを作成して、categoriesテーブルが作成されていると仮定します。 rails destroy model category ②削除用のファイルを新規作成する。 次にテーブル削除するために新規でマイグレーションファイルを作成します。(GI上では削除できないため) 以下を記載します。 rails generate migration 任意のファイル名 ファイル名は後に削除するので何でも構いません。 ここでは、「delete_category_table」としておきます。 ③削除用のファイルに削除したいテーブルを記載。 マイグレーションファイルを開いて、以下を記載します。 delete_category_table.rb class DeleteCategoryTable < ActiveRecord::Migration[5.2] def change drop_table :categories  ←drop_table :削除したいテーブルを記載 end end ④マイグレーションして、削除を行う。 最後はマイグレーションして、テーブルの削除を反映させます。 rails db:migrate 以上となります。 終わりに 当初はテキストエディタ上で右クリック→deleteで削除した気になっていました。 当然それではきちんと削除されている訳なく…。 しっかりと根本から削除する必要があるのだなと学びました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】WIndows環境でrails db:resetしたとき、Couldn't drop database 'db/development.sqlite3'のエラーの対処法

症状 Windows環境でrails db:resetしたとき、下記エラーが表示されてしまいました。 マイグレーションファイルを更新して、データベースにあるテーブルの内容を更新したく、rails db:resetを実行しました。 ターミナル rails db:reset Permission denied @ apply2files - C:/Users/ユーザー名/environment/sampleApp/db/development.sqlite3 Couldn't drop database 'db/development.sqlite3' rails aborted! Errno::EACCES: Permission denied @ apply2files - C:/Users/ユーザー名/environment/sampleApp/db/development.sqlite3 bin/rails:4:in `<main>' Tasks: TOP => db:drop:_unsafe (See full trace by running task with --trace) 以下のコマンドで検索すると、どうやらRails自体のバグがあるようで、Windows環境で特定のコマンドを実行しようとすると、上記のようなエラーが発生するようです。 該当コマンドは以下です。 対象コマンド rails db:drop rails db:reset rails db:migrate:reset 今回はrails db:resetが該当します。 解決方法 railsのdbのフォルダに移動し、手動でデータベースを削除する必要があるとのこと。 実際にやってみると、正常にデータベースが削除できました。 del development.sqlite3 migrationファイルを編集し、下記コマンドを実行すると正常にテーブルが更新できました。 rails db:migrate 参考 【Ruby on Rails】rails db:dropコマンドを実行したとき、エラーメッセージ「Couldn’t drop database ‘db/development.sqlite3’ rails aborted!」が表示されてしまう原因と解決策をお伝えします https://www.tairaengineer-note.com/rails-couldnt-drop-database/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

capistrano 踏み台サーバがある場合のconfig/deploy/production.rbの書き方

構成 -------------------- target_server user: deploy key: id_rsa.pemが必要 -------------------- ^ | -------------------- bastion_server.com user: bastion_user -------------------- ^ | -------------------- local -------------------- config/deploy/production.rb server "target_server", user: "deploy", roles: %w{app db web}, my_property: :my_value set :ssh_options, { keys: %w(~/.ssh/id_rsa.pem), forward_agent: false, user: 'deploy', proxy: Net::SSH::Proxy::Command::new('ssh bastion_user@bastion_server.com -W %h:%p') } 参考 config/deploy/production.rbの設定について https://gist.github.com/chansuke/737784de811f140853239daa7b6b75ef SSHのProxyCommandについて https://dev.classmethod.jp/articles/direct-ssh-by-proxycommand/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby lastメソッド

lastメソッドとは lastメソッドは配列の要素を取り出すときにその配列の中の最後の要素を取得するメソッド。 配列の要素がない場合はnilを返す。 lastメソッドの書き方 配列名.last 配列名.last(引数) colors = ["red", "blue", "yello", "black"] puts colors.last puts colors.last(3)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby firstメソッド

firstメソッドとは firstメソッドは配列の要素を取り出すときにその配列の中の最初の要素を取得するメソッド。 配列の要素がない場合はnilを返す。 firstメソッドの書き方 配列名.first 配列名.first(引数) 引数がある場合は配列の中の最初の要素からその引数の数の要素を配列で返す。 foods = ["sandwich", "tacos", "sushi", "nuts", "pasta"] puts foods.first puts foods.first.(2) 参考サイト TechAcademy
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails初学者によるRailsチュートリアル学習記録⑦ 第5章

目次 1. はじめに 2. 第5章の概要 3. 学習内容 4. 終わりに 1. はじめに この記事は、Rails初学者の工業大学三年生がRailsチュートリアルの学習記録をつけるための記事です。 筆者自体がRailsやWebについて知識が少ないので、内容の解釈などに間違いがある可能性があります。(その時はコメントで指摘してくださると助かります!) Railsチュートリアル内ではRailsの内容以外にも、gitでのバージョン管理やHerokuを使ったデプロイも学習しますが、gitに関しては既に私が学習済みのため学習記録には記述しません。 演習の記録も省略します。 2. 第5章の概要 この章ではBootstrapを使用して、サンプルアプリケーションにカスタムスタイルを組み込みます。 その途中でビューファイルなどの既存のファイルを扱いやすくなるような パーシャル、アセットパイプライン、名前付きルーティングを学んでいきます。 ただ、Bootstrapはフロント寄りの内容なので細かく記録はしません。 アセットパイプラインとは パーシャル パーシャルとは パーシャルでHTMLを分割する 名前付きルート 名前付きルートを使う準備 名前付きルートをルーティングに設定する 3. 学習内容 1. アセットパイプライン 1-1. アセットパイプラインとは アセットパイプラインとはCSS, JavaScript, ビューで使用する画像といったアプリケーション内の静的コンテンツを、 1つのファイルにまとめる仕組みのことです。 Railsアプリケーションの開発においてそれらのファイルはapp/assetsの下にある、 stylesheets, images, javascriptsといったディレクトリに保存します。 このように、ファイル自体は別々のディレクトリに保存されていますが、 アセットパイプラインによってそれらのファイルにアクセスするときは、 ファイル名のみでアクセスすることができます。 例えば、app/assets/images/ディレクトリに保存した画像をビューで表示させたいときは、以下のように書きます。 <%= link_to image_tag("rails.svg", alt: "Rails logo", width: "200px"), "https://rubyonrails.org/" %> image_tagというヘルパーを使用することで、Railsがapp/assets/images/ディレクトリ内からrails.svgという画像を探してくれます。 これによる主なメリットは本番環境でのユーザー体験にあります。 プログラマとしてはファイルの種類ごとにディレクトリが分かれていたほうが開発しやすいですが、 その分読み込み時間が長くなってしまいます。 この問題をアセットパイプラインは、分割されたファイルを結合し最小化するという方法で読み込み時間を短くして解決しています。 2. パーシャル 2-1. パーシャルとは RailsではHTMLヘッダーやHTML shim(IEに対応させるためのコード)といった1つのグループとして考えられるようなコードを、 それぞれのファイルに分割して、実際にそれを使用したいファイルで分割したファイルを呼び出すといった方法を取ることができます。 この方法によりビューの共通部分を記述したapplication.html.erbが以下のように書き換えられます。 ↓書き換え前 app/views/layouts/application.html.erb <!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]--> </head> <body> <header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", '#', id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", '#' %></li> <li><%= link_to "Help", '#' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav> </div> </header> <div class="container"> <%= yield %> </div> </body> </html> ↓書き換え後 app/views/layouts/application.html.erb <!DOCTYPE html> <html> <head> <title><%= full_title(yield(:title)) %></title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <%= render 'layouts/shim' %> <!-- パーシャル使用部分1 --> </head> <body> <%= render 'layouts/header' %>  <!-- パーシャル使用部分2 --> <div class="container"> <%= yield %> </div> </body> </html> 書き換え後のコードでは、コメントがある2箇所でパーシャルを使用しています。 1つ目は<%= render 'layouts/shim' %>という行で、IEに対応するための部分を別のファイルに移してそれを読み込んでいます。 読み込むときに使用しているヘルパーはrenderというヘルパーで、このヘルパーが実行されると app/views/layouts/_shim.html.erbというファイルを探してその内容を挿入します。 2つ目は<%= render 'layouts/header' %>という行で、ヘッダー部分を読み込んでいます、 このヘルパーではapp/views/layouts/_header.html.erbというファイルを探してその内容を挿入します。 2つの例から見て分かるように、パーシャルはファイル名の先頭にアンダーバーを入れる必要があります。 これによってRailsはパーシャルかどうかを識別しています。 2-1. パーシャルでHTMLを分割する 先述したコードはパーシャルを呼び出す側のコードです。 次は、分割されたパーシャルの内容を見ていきます。 ↓HTML shimのパーシャル app/views/layouts/_shim.html.erb <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]--> ↓headerのパーシャル app/views/layouts/_shim.html.erb <header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", '#', id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", '#' %></li> <li><%= link_to "Help", '#' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav> </div> </header> 上記の二つのコードは元々application.html.erbに記述されていたコードです。 つまり、パーシャルを使用したいときは、アンダーバーが名前の初めについたファイルを app/views/layoutsの下に作成し、そこにコードをカット&ペーストして、元のファイルでrenderヘルパーを記述するだけで使用できます。 3. 名前付きルート 3-1. 名前付きルートとは 名前付きルートとはビューへのリンクなどを書くときに、 <a href="/static_pages/about">About</a> 上記のようにURLを直接記述するのではなく、 <%= link_to "About", about_path %> このabout_pathのようにリンク先を書くことができるようになるものです。 名前付きルートを使用することで、上記の例であればabout_pathの定義を変えることで about_pathが使用されているURLをすべて変更できるので、柔軟性が高まるといったメリットがあります。 3-2. 名前付きルートを使う方法 ここからは名前付きルートを使うための準備をしていきますが、 既に名前付きルートを使用した場面があります。 それがroot 'application#hello'というコードです。 これはルートURL("/")をhelloアクションに紐づけているコードで、これによりroot_pathとroot_urlといったメソッドが 使用できるようになっています。 上記のルーティングはルートURLの名前付きルートなので、それ以外のページを同じように書くことはできません。 例えばhelpページのルーティング get 'static_pages/help'を変更するときは、 get '/help', to: 'static_pages#help'と書きます。 これによりhelp_pathやhelp_urlといった名前付きルートが使用できるようになります。 ちなみにこの2つは返ってくる文字列が違います。 ・help_path → '/help' ・help_url → 'https://www.example.com/help' pathはルートURL以下の文字列、urlは完全なURLの文字列が返ってきます。 また上記の方法ではアクション名を使った名前付きルートになりますが、 全く違う名前を使用したいときはas:オプションを使用します。 as:オプションを使った書き方は以下の通りです。 get '/help', to: 'static_pages#help', as: 'herupu' このコードではhelpアクションをherupuという文字列を使って表しています。 よって、herupu_pathやherupu_urlが使用できるようになります。 4. 終わりに 第5章ではこれまでに作成した、ビューへのスタイルの適用を中心に学びました。 私の記事では、フロントエンドの内容より、バックエンドの内容を振り返りたいのでBootstrapやSassの内容でなく、 アセットパイプラインやパーシャルといったRailsの特長と言える部分について記録するようにしました。 前回の投稿から期間が空きましたが、第6章の内容まで進めた後にこの記事を書いているので次の記事はすぐに投稿する予定です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RSpec(ユーザー新規登録の結合テスト)

結合テストコードを書く方針 結合テストコードを書く方針は、ユーザーがたどる一連の流れを確認することです。 今回は、以下のexampleについてテストしました。 ユーザー新規登録できるとき 正しい情報を入力すればユーザー新規登録できてトップページに移動する トップページに移動する トップページにサインアップページへ遷移するボタンがあることを確認する 新規登録ページへ移動する ユーザー情報を入力する サインアップボタンを押すとユーザーモデルのカウントが1上がることを確認する トップページへ遷移したことを確認する カーソルを合わせるとログアウトボタンが表示されることを確認する サインアップページへ遷移するボタンや、ログインページへ遷移するボタンが表示されていないことを確認する RSpec.describe 'ユーザー新規登録', type: :system do before do @user = FactoryBot.build(:user) end context 'ユーザー新規登録ができるとき' do it '正しい情報を入力すればユーザー新規登録ができてトップページに移動する' do visit root_path expect(page).to have_content('新規登録') visit new_user_registration_path fill_in 'ニックネーム', with: @user.nickname fill_in 'Eメール', with: @user.email fill_in 'パスワード', with: @user.password fill_in 'パスワード(確認用)', with: @user.password_confirmation expect{ find('input[name="commit"]').click }.to change { User.count }.by(1) expect(current_path).to eq(root_path) expect( find('.user_nav').find('span').hover ).to have_content('ログアウト') expect(page).to have_no_content('新規登録') expect(page).to have_no_content('ログイン') end end end 以下にコードの説明をしました ルートパスに実際に遷移することを表現している visit root_path visitで訪れたページの中に、'新規登録'という文字列があるかを判断してる expect(page).to have_content('新規登録') 新規登録ページへ移動 visit new_user_registration_path ユーザー情報を入力 fill_in 'ニックネーム', with: @user.nickname fill_in 'Eメール', with: @user.email fill_in 'パスワード', with: @user.password fill_in 'パスワード(確認用)', with: @user.password_confirmation fill_in 'フォームの名前', with: '入力する文字列'のように記述することで、フォームへの入力を行うことができます。'フォームの名前'は検証ツールにて確認しました→<label for="user_nickname>ニックネーム</label> サインアップボタンを押すとユーザーモデルのカウントが1上がることを確認する expect{ find('input[name="commit"]').click }.to change { User.count }.by(1) find('クリックしたい要素').clickと記述することで、実際にクリックができます。 expect{ 何かしらの動作 }.to change { モデル名.count }.by(1)と記述することによって、モデルのレコードの数がいくつ変動するのかを確認できます。 トップページへ遷移したことを確認する expect(current_path).to eq(root_path) カーソルを合わせるとログアウトボタンが表示されることを確認する expect( find('.user_nav').find('span').hover ).to have_content('ログアウト') find('ブラウザ上の要素').hoverとすることで、特定の要素にカーソルをあわせたときの動作を再現できます。今回、span要素は他でも使われているため、その親要素のuser_navクラスもあわせて指定しました。 サインアップページへ遷移するボタンや、ログインページへ遷移するボタンが表示されていないことを確認する expect(page).to have_no_content('新規登録') expect(page).to have_no_content('ログイン') have_no_contentは文字列が存在しないことを確かめるマッチャです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsの設計思想「CoC」について

はじめに まずRailsには設計思想として3つ強く打ち出しています。 1. CoC (Convention over Configuration) 2. DRY (Don’t Repeat Yourself) 3. REST(Representational State Transfer) 今回は1のCoCについて解説したいと思います。 CoCとは 直訳すると「設定より規約」という意味になります。例えばユーザー情報を表現するモデルをUserモデルとした場合、Railsでは以下の様なルールに則って開発します。 データベースのモデル名の複数形にする(Users) /usersというURLは社員の一覧を表す ユーザーID:1のユーザー情報を表すURLは/users/1になる 上記の様なルールで書くとそれぞれに細かく設定を紐付ける作業を省略できます。 「便利ですね〜」 またこれらの規約に従うとプログラム内に規律が生まれ以下の様な、メリットもあります。 多くの設定ファイルを書かなくて良い 共通のルールがあることで他のエンジニアとスムーズなコミュニケーションが取れる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Userモデルに後からDeviseを入れたらログインできなくなった事件

起こった問題 Webサービスを作ろうとUserモデルを作成。 とりあえずRailsチュートリアルに倣って進めるも、Deviseが使いたくなったので途中で方針転換。 メール認証機能を作ったところでDeviseを導入、作り直すことに。 ユーザーの作成はできた(?)がどうもログインができず。 (エラーは出ないが「メールアドレスまたはパスワードが正しくない」と言われる。) ※もちろん正しいものでトライしてます。 結論 UserモデルにRailsチュートリアル内で作った名残が残っていたせいで不具合が起き、 encrypted_passwordにパスワードが保存されなかったことが原因でした。 user.rb class User < ApplicationRecord (以下抜粋) attr_accessor :remember_token, :activation_token, :activation_digest, :password_digest #←ここ消す has_secure_password #←ここ消す Deviseでいいようにやってくれるのでhas_secure_passwordとpassword_digest属性は不用。消しましょう。ということでした。 残してると色々メソッド名やらなんやらがバッティングしちゃってうまくいきません。 潔く思い出はさよならしましょう。 解決に至った経緯 とりあえずブラウザで作ったユーザーをコンソールで見てみる。 #ブラウザから作ったユーザーを取得 user = User.last user.valid? => false user.encrypted_password => "" user.valid?がfalse。 user.encrypted_passwordが""。 あれ、パスワード保存されてなくない? 疑惑① フォームからパスワードの送信or保存が上手くいってない? であれば、コンソール上でユーザーを作成してみる。 user2 = User.new(name: "Test Taro", email: "test@example.com", password: "password", password_confirmation: "password") user2.valid? => true user2.valid?がtrueになったのでログインいけるかな?と思いきや やはりアドレスかパスワードが違うと言われログインできない。 コンソールで見てみると user2.encrypted_password => "" user2.password => "password" やっぱりencrypted_passwordが保存されてない。 一応、userのpassword属性には値が入っている。 であればフォームのせいではなさそう。(自動生成されたものからいじってないし) 疑惑② もともと作っていたパスワード周りの何やかんやが悪さしているな。 一旦models/user.rbを見返す。いらないものは消していこう。 has_secure_password不要! →消す →ログインを試みる →エラー発生 ArgumentError in Devise::SessionsController#create wrong number of arguments (given 1, expected 0) Extracted source (around line #67): def password=(new_password) @password = new_password self.encrypted_password = password_digest(@password) if @password.present? #ここに赤線入ってる end # Verifies whether a password (ie from sign in) is the user password. 引数いらないのに1個渡しちゃってるらしい。 何か思い当たる節は・・・ ん、password_digestという聞き覚えのある単語・・!!! attr_accessorに:password_digestが残ってたので消す →解決!!!! 参考 【Rails】devise実装後のユーザー新規登録時のエラー[ArgumentError in Users::RegistrationsController#create]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

エラーメッセージの日本語翻訳(実装からエラー解決まで)

はじめに アプリケーションで英語エラーメッセージを日本語化する実装を行なったため、その過程及び実装中で起こったエラーとその解決を記録として残します。 条件 Ruby: 2.6.5 Rails: 6.0.3.6 Git: 2.30.1 Unicorn: 5.4.1 目次 事前準備 エラーメッセージの日本語訳 本番環境に反映 エラーとその解決 おわり 1. 事前準備 viewの編集 まずは、エラーメッセージ専用のviewを作成。 複数のviewで使用することを想定されているものは、別で切り出して用意しておき、呼び出すだけでいいように準備しておきます。 今回は、views / shared に_error_messages.html.erbファイルを自作しました。 views └ shared └ _error_messages.html.erb _error_messages.html.erbファイルの中身 app/views/shared/_error_messages.html.erb <% if model.errors.any? %> <div class="error-alert"> <ul> <% model.errors.full_messages.each do |message| %> <li class='error-message'><%= message %></li> <% end %> </ul> </div> <% end %> model.errors.any?を記述することで、どのモデルのバリデーションにも対応できるようにします。 次に、このエラーメッセージを表示さたいviewに呼び出します。 エラーメッセージの呼び出し renderを用いてエラーメッセージを表示させたい部分に、以下のように記述する。 記述例 <%= form_with model: @purchase_address, url: item_purchases_path, id: 'charge-form', class: 'transaction-form-wrap',local: true do |f| %> <%# エラーメッセージの呼び出し %> <%= render 'shared/error_messages', model: f.object %> <div class='credit-card-form'> <h1 class='info-input-haedline'> クレジットカード情報入力 </h1> <%# 以下省略 %> これで、エラーメッセージの表示が完了。 2. エラーメッセージの日本語訳 日本語化の設定 config / application.rb 内を以下のように編集。 config/application.rb module アプリケーション名 class Application < Rails::Application config.load_defaults 6.0 # 日本語の言語設定 config.i18n.default_locale = :ja end end 続いて、Gemfileにrails-i18nというGemを導入 → ターミナルで、bundle install Gemfile gem 'rails-i18n' ターミナル bundle install ※ application.rb内に日本語の設定の記述をしていないと、Gemを導入してもに日本語で設定されないため、必ず記述。 現段階ではまだ、ログイン / 新規登録と一部エラーメッセージが英語であるため以下の作業で完全に日本語化していく。 localeファイル 色々な言語に対応できる言語ファイル。 ファイルは、YAMLというファイル形式で記述する。 config / localesディレクトリに、devise.ja.ymlファイルを作成。 config └ locales └ devise.ja.yml devise.ja.ymlファイルには、下記のサイトより記述内容を拝借して貼り付けする。 devise-i18n/ja.yml config/locales/devise.ja.yml ja: activerecord: attributes: user: confirmation_sent_at: パスワード確認送信時刻 confirmation_token: パスワード確認用トークン confirmed_at: パスワード確認時刻 created_at: 作成日 current_password: 現在のパスワード current_sign_in_at: 現在のログイン時刻 current_sign_in_ip: 現在のログインIPアドレス email: Eメール encrypted_password: 暗号化パスワード failed_attempts: 失敗したログイン試行回数 last_sign_in_at: 最終ログイン時刻 last_sign_in_ip: 最終ログインIPアドレス locked_at: ロック時刻 password: パスワード # 以下略 ※ インデントにミスがあるとエラーを起こすため、よく確認しておく。 これで、ログイン / 新規登録のエラーメッセージの日本語化は完了。 しかしまだ一部英語が残るため、最後は手動で日本語化していく。 ja.ymlファイルを作成 config / localesディレクトリに、ja.ymlファイルを作成。 config └ locales ├ devise.ja.yml └ ja.yml インデントに気をつけて日本語化したい部分を記述していく。 config/locales/ja.yml ja: activerecord: attributes: user: nickname: ニックネーム item: name: 商品名 description: 商品の説明 # ~ 中略 ~ # ActiveModelの場合 activemodel: attributes: purchase_address: postcode: 郵便番号 region_id: 都道府県 city: 市区町村 block: 番地 phone_number: 電話番号 token: クレジット情報 テストコードを書いている場合 エラーメッセージを日本語化したため、テストコードのエラー文も英語から日本語に変換しておく。 context '新規登録ができない時' do it 'nicknameが空では登録できない' do @user.nickname = '' @user.valid? expect(@user.errors.full_messages).to include('ニックネームを入力してください') end it 'emailが空では登録できない' do @user.email = '' @user.valid? expect(@user.errors.full_messages).to include('Eメールを入力してください') end it '重複したemailは登録できない' do @user.save another_user = FactoryBot.build(:user, email: @user.email) another_user.email = @user.email another_user.valid? expect(another_user.errors.full_messages).to include('Eメールはすでに存在します') end 3. 本番環境に反映 以下の記述は、自動デプロイの実装を行なっている程で話をしています。 変更内容はリモートリポジトリにcommitしてpushしておく。 (ブランチを切っていたら、mergeまで実行) ターミナル(EC2内) ① pemファイルがあるディレクトリに移動 % cd .ssh ② EC2にログイン .ssh % ssh -i <鍵の名前>.pem ec2-user@ <Elastic IP> ③ 開発中のアプリケーションのディレクトリに移動 [ec2-user@ip-111-22-33-444 ~]$ cd /var/www/開発中のアプリケーション名 ⑤ GitHubからEC2へ反映 [ec2-user@ip-111-22-33-444 リポジトリ名]$ git pull origin master ④ 現在動いているプロセスの確認 [ec2-user@ip-111-22-33-444 リポジトリ名]$ ps aux | grep unicorn ec2-user 18365 0.1 12.2 483188 123304 ? Sl 05:11 0:01 unicorn master -c ..... ec2-user 18406 0.0 12.2 489520 123072 ? Sl 05:11 0:00 unicorn worker[0] -c ..... ec2-user 18704 0.0 0.0 119436 964 pts/0 S+ 05:25 0:00 grep --color=auto unicorn ⑤ 'unicorn master'のプロセスID(左から2番目の番号)をkillする [ec2-user@ip-111-22-33-444 リポジトリ名]$ kill 18365(上記の場合) ターミナル(ローカル) ⑥ サーバー再起動 % bundle exec cap production deploy 4. エラーとその解決 本番環境にデプロイした時に実際に起こったエラーと解決までの作業を記述します。 本番環境で「新規登録」ページに遷移するとエラー ①エラーログの確認 ターミナル ① logディレクトリに移動 [ec2-user@ip-111-22-33-444 リポジトリ名]$ cd log ② ls でlogディレクトリの中身を確認 [ec2-user@ip-111-22-33-444 log]$ ls production.log unicorn.stderr.log unicorn.stdout.log ③ production.log でログの確認('tail -f'でログの10行分を表示) [ec2-user@ip-111-22-33-444 log]$ tail -f production.log 実際にエラーがあった時の表示 怪しいのは、一番上のこの部分。 ターミナル [ee4c13d3-......] ActionView::Template::Error (undefind method `map' fo "translation missing: ja.data.order":String): translation missing: ja.data.ordeということから、日本語訳がうまくいっていないんじゃないか...?と考えられる。 【解決】 プロセスを停止(kill)した上で、再起動を行うと反映された。 プロセス停止 → サーバー再起動の手順が上手くいっていなかった...? 本番環境のディレクトリに日本語翻訳したファイルがない 本番環境のディレクトリに日本語訳するためのファイル(devise.ja.yml・ja.yml)があるか確認(config / locales の中を確認)。 ターミナル ① ls でconfigがあるか確認 [ec2-user@ip-111-22-33-444 リポジトリ名]$ ls Capfile README.md babel.config.js config.ru furima.dio node_modules public revisions.log storage vendor Gemfile Rakefile bin current lib package.json releases shared test yarn.lock Gemfile.lock app config db log postcss.config.js repo spec tmp ② configディレクトリに移動 [ec2-user@ip-111-22-33-444 リポジトリ名]$ cd config ③ config内のディレクトリを確認 [ec2-user@ip-111-22-33-444 config]$ ls application.rb cable.yml database.yml deploy.rb environments locales routes.rb storage.yml webpack boot.rb credentials.yml.enc deploy environment.rb initializers puma.rb spring.rb unicorn.rb webpacker.yml ④ localesディレクトリに移動 [ec2-user@ip-111-22-33-444 config]$ cd locales ⑤ localesの中身を確認 [ec2-user@ip-111-22-33-444 locales]$ ls devise.en.yml en.yml 長々と書きましたが、これは1つずつ確実に中身を確認するために記述したため、本来は以下の記述でlocalesディレクトリまで移動できます。 ターミナル [ec2-user@ip-111-22-33-444 リポジトリ名]$ cd config/locales [ec2-user@ip-111-22-33-444 locales]$ ls devise.en.yml en.yml localesの中みを見ると、日本語訳にするためのファイル(devise.ja.yml・ja.yml)が見当たらない。 【原因】 コードの変更を、commit → push(もしくはmerge)した時点で満足し、GitHubからEC2へ反映していなかった。 git push origin master のし忘れ。 【解決】 ターミナルでEC2へ変更を反映。 ターミナル [ec2-user@ip-111-22-33-444 リポジトリ名]$ git pull origin master 5. おわり 本番環境に反映されない時は、以下の確認を行う。 変更・追加をリモートリポジトリにcommit→push(またはmerge)しているか GitHubからEC2へ(git pull origin master)したか EC2インスタンスの再起動 エラーログの確認
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]herokuで画像の保存場所にAmazonS3を使用してみる

はじめに 本記事ではAWSの設定等は含まれておりません。あらかじめご了承ください AmazonS3とは S3とは、AWSが提供するサービスの一つで、インターネット上にデータを保存する箱を借りられるサービスというものです。 S3を利用することで、画像を保存したり、保存してある画像を取得したりすることができます。 実装方法 まずは画像投稿した際などに画像の保存先がS3となるように変更していきます。 はじめにS3が使用できるようにしましょう。 #一番下に記述 gem "aws-sdk-s3", require: false ※bundle installを忘れずに!! 続いて、画像の保存先を指定します。 config/environments/development.rb # ~省略~ #config.active_storage.service = :local #コメントアウト!!!!! config.active_storage.service = :amazon # ~省略~ 次に、S3で使用するバケット名とリージョン名を記述します。 config.storage.yml test: service: Disk root: <%= Rails.root.join("tmp/storage") %> local: service: Disk root: <%= Rails.root.join("storage") %> #以下を追記 amazon: service: S3 region: ap-northeast-1 bucket: ご自身の「バケット名」を入力 #ここまで # ~省略~ 次に、S3にアクセスするための認証情報を設定します。 これは機密情報なので環境変数にいれます。 % vim ~/.zshrc 以下を記述してください export AWS_ACCESS_KEY_ID="CSVファイルのAccess key IDの値を貼り付け" export AWS_SECRET_ACCESS_KEY="CSVファイルのSecret access keyの値を貼り付け" なお、ここにいれるものは、AWSでIAMユーザを作った際にダウンロードする「new_user_credentials.csv」に記載してあります。 入力したら保存して(esc+:wq)してパスを通します % source ~/.zshrc ここまでで、環境変数を設定することができました。 実際にソースコード内で環境変数を使用して、S3への認証情報を記述しましょう。 config/storage.yml #省略 amazon: service: S3 region: ap-northeast-1 bucket: (自身のバケット名が記載されている状態です) #追加 access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> # ~省略~ ここまででローカル環境では保存先がS3になっているかと思います。何かを投稿した時、AWS側で確認することができるかと思います。 さあ!後少し!! ローカル同様に、heroku上でも環境変数を設定します。Herokuで環境変数を扱うには、「heroku config:setコマンド」を打つ必要があります。 % heroku config:set AWS_ACCESS_KEY_ID="CSVファイルのAccess key IDの値を貼り付け" % heroku config:set AWS_SECRET_ACCESS_KEY="CSVファイルのSecret access keyの値を貼り付け" 反映されたかどうかは、以下のコマンドで確認できます % heroku config あ!!!忘れてた、、、 本番環境でも保存先を変更しておきましょう config/environments/production.rb # ~省略~ #config.active_storage.service = :local #コメントアウト config.active_storage.service = :amazon # ~省略~ あとは、これらの変更点をherokuに反映っと、、、 % git push heroku master 完成!!!! #補足(エラー発生した人向け) 画像の保存先の設定を変更することにより、画像の参照先がアプリケーション内からS3へ置き換わります。 当然、S3導入前に投稿した画像が表示できなくなります。 それが嫌だ!!という方や何かしらのエラーが出た方は以下のコマンドを実行し、一度データベースをリセットしてください。 この際、データベースに保存されていたデータは全て消えるため注意しましょう。 % heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop db:create db:migrate おわりに 前回の記事と合わせれば、ひとまずherokuでのデプロイは完璧にできるかと思います。 次はCircleCIやDocker、AWSの導入に挑戦していきます!!! 前回の記事([Rails]ノーエラーでherokuへデプロイしていく) https://qiita.com/tochisuke221/items/62d114989e872fa4e50a
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【rails6】結合テストエラーの解決 `it` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).

こんにちは! 今日も結合テストで犯した凡ミスについて共有していこうと思います 凡ミスばかりですみません… でもこういった凡ミスで無駄な時間を過ごしてしまう方々が一人でも減ればなぁと信じて 是非読んでいってください! では、まずは今日のエラーをご紹介 発生したエラー % bundle exec rspec spec/system/comments_spec.rb # この結合テストを実行した際に Failure/Error: it 'ログインしたユーザーはコメントできる(自分の投稿にコメントする場合)' do # 省略 `it` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block). # ↑このエラーが発生しました↑ さて、このエラー文 `it` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block). を日本語訳してみましょう it` は、サンプル内(例:`it` ブロック)や、サンプルのスコープ内で実行されるコンストラクト(例:`before`、`let` など)からは利用できません。サンプルグループ(例:`describe`や`context`ブロック)でのみ利用可能です。 みなさん英文を見た瞬間に「うわっ…」となるかもしれませんが、ここは慣れましょう 便利な翻訳サイトのリンクは下に貼りますが、できる限りご自身で読み解くことをお勧めします ※今はQiita投稿の為翻訳してます では、原因となるコードを見てみましょう comments_spec.rb it '空欄のコメント送信はできない' do it 'ログインしたユーザーでも空欄コメントは送信できない' do # ログインし、root_pathにいることを確認する sign_in(@article1.user) expect(current_path).to eq root_path expect(page).to have_no_content('ログイン') # @article1の詳細ページに遷移する visit article_path(@article1) expect(page).to have_content(@article1.title) # コメント欄があることを確認、フォームに入力する expect(page).to have_selector(".send-comment-text") fill_in "コメントを入力", with: '' # コメントを送信しても、Commentモデルのカウントが上がらない事を確認する expect{find('input[name="commit"]').click}.to change { Comment.count }.by(0) # コメントがページこのページ内に存在していないか確認する expect(page).to have_no_content(@comment) end end 何がいけないか、もうお分かりですよね?? itの中にitを書いてしまっている!! という事です 「別のテストコードをコピペ活用する中で、不要なit文を削除し忘れた」ということですね では、解決していきましょう comments_spec.rb it 'ログインしたユーザーでも空欄コメントは送信できない' do # ログインし、root_pathにいることを確認する sign_in(@article1.user) expect(current_path).to eq root_path expect(page).to have_no_content('ログイン') # @article1の詳細ページに遷移する visit article_path(@article1) expect(page).to have_content(@article1.title) # コメント欄があることを確認、フォームに入力する expect(page).to have_selector(".send-comment-text") fill_in "コメントを入力", with: '' # コメントを送信しても、Commentモデルのカウントが上がらない事を確認する expect{find('input[name="commit"]').click}.to change { Comment.count }.by(0) # コメントがページこのページ内に存在していないか確認する expect(page).to have_no_content(@comment) end これだけです。上記との違いは、重複されていたit文を片方削除しました。 ターミナルで実行します % bundle exec rspec spec/system/comments_spec.rb Comments コメントできるとき ログインしたユーザーはコメントできる(自分の投稿にコメントする場合) ログインしたユーザーはコメントできる(他人の投稿(@article2)にコメントする場合) コメントできないとき ログインしていないユーザーはコメントできない 空欄のコメント送信はできない Finished in 20.88 seconds (files took 1.77 seconds to load) 4 examples, 0 failures うん、OKです!! では、下記ご参考まで… 便利な翻訳サイト DeepL様 https://www.deepl.com/translator
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails6】deviseで独自カラムを追加して使用する方法 ①

はじめに Railsのログイン認証で、deviseを使用する機会が多いかと思いますが、独自のカラムを追加して使用する方法をご紹介します。 今回のテーマは、独自カラムの追加とログイン時に独自のカラムで行えるようにすることにします。 環境 MacOS : Big Sur Ruby : 3.0.1 Rails : 6.1.3.1 ① gem devise 追加 Gemfile に追記していきます。 Gemfile gem 'devise' bundle install コマンドの実行 bundle install ② devise インストール deviseをインストールする rails g devise:install コマンドを実行 rails g devise:install Running via Spring preloader in process 4466 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Depending on your application's configuration some manual setup may be required: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. * Required for all applications. * 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" * Not required for API-only Applications * 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> * Not required for API-only Applications * 4. You can copy Devise views (for customization) to your app by running: rails g devise:views * Not required * =============================================================================== ③ Userモデル 作成 Userモデルを追加する rails g devise user コマンドを実行 rails g devise user Running via Spring preloader in process 4487 invoke active_record create db/migrate/20210505〇〇〇〇〇〇_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users 上記コマンドを実行すると、DeviseのUserモデルが作成されるので、作成されるマイグレーションファイルを編集し独自カラムを追加します。 ④ マイグレーションファイル 編集 /db/migrate/20210505〇〇〇〇〇〇_devise_create_users.rb ファイルを編集していきます。 ※ 生成されたマイグレーションファイルで、一部コメントアウト # t.string されているので、必要に応じて # を外します。 20210505〇〇〇〇〇〇_devise_create_users.rb_編集前 # frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.1] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable # t.integer :sign_in_count, default: 0, null: false # t.datetime :current_sign_in_at # t.datetime :last_sign_in_at # t.string :current_sign_in_ip # t.string :last_sign_in_ip ## Confirmable # t.string :confirmation_token # t.datetime :confirmed_at # t.datetime :confirmation_sent_at # t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true # add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end 20210505〇〇〇〇〇〇_devise_create_users.rb_編集後 # frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.1] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" #今回追加 t.string :user_code, null: false, default: "" #ユーザコード (ログインにも使用) t.string :user_last_name, null: false, default: "" #姓 t.string :user_first_name, null: false, default: "" #名 t.string :user_status, null: false, default: "enable" #ステータス ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, default: 0, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # メール認証をする場合 ## Lockable t.integer :failed_attempts, default: 0, null: false # ロック機能を利用する場合 t.string :unlock_token # ロック解除をメール等で行う場合 t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true add_index :users, :confirmation_token, unique: true add_index :users, :unlock_token, unique: true #今回追加 add_index :users, :user_code, unique: true end end 上記のように、コメントアウト・追加したいカラムを追加していきます。 ※ 今回は、初めの段階で、予定している使用機能のコメントアウト・追加したいカラムを追記しています。 マイグレーションした後でも、機能・カラムの追加は行えます。 ⑤ マイグレーション 実行 マイグレーションを行う rails db:migrate コマンドを実行 rails db:migrate == 20210505〇〇〇〇〇〇 DeviseCreateUsers: migrating ================================ -- create_table(:users) -> 0.0041s -- add_index(:users, :email, {:unique=>true}) -> 0.0016s -- add_index(:users, :reset_password_token, {:unique=>true}) -> 0.0014s -- add_index(:users, :confirmation_token, {:unique=>true}) -> 0.0016s -- add_index(:users, :unlock_token, {:unique=>true}) -> 0.0012s -- add_index(:users, :user_code, {:unique=>true}) -> 0.0015s == 20210505〇〇〇〇〇〇 DeviseCreateUsers: migrated (0.0134s) ======================= ここまで行うと、ログイン機能が使用できるようになりますが、 今回は、独自カラムを追加しているので、ビューやコントローラをカスタマイズする必要があります。 長くなりましたので、記事を分けてご紹介しようと思います。 次回は、ビューのカスタマイズを行っていきたいと思います。 ▽次の記事はこちら▽ 【Rails6】deviseで独自カラムを追加して使用する方法 ② ~ 申し訳ございません。公開までしばらくお待ちください。 ~
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む