20210731のRailsに関する記事は19件です。

railsでGCP Natural Language APIを使ってクソアプリを作ってみた。

アプリの見た目 試しに「上京しました。」と入力して送信すると。 ↓ こんな感じのviewが帰ってきます。パーソナリティはポンコツbabyだそうです。  APIの利用手順 下記ページへ移動 「コンソールへ移動」をクリック *GCPへの登録をしていない方は、「無料で開始」というボタンが表示されるので、 手順に従って利用を開始してください。確かクレジットカードの登録が必要だったと思いますが、 有料サービスを使用しなければ基本無料で使用できます。 「APIとサービス」にカーソルを合わせて、ライブラリをクリックします。 検索フォームが出てくるので「Natural Language API」等で検索して、 「Cloud Natural Language API」をクリック 「有効にする」をクリックしAPIの使用を有効にします。 画面遷移ができれば有効化は完了です。 *左側の「割り当て」からAPIの発行回数を制限できます。心配な人は制限を付けておきましょう。 続いてAPIを発行します。 先ほどの手順でクリックしたライブラリの下に「認証情報」というリンクがあるので、クリックします。 「認証情報を作成」をクリックするとタブが出てくるので、「APIキー」をクリック。 APIキーが作成されます。作成されたキーを使用します。 APIキーは大事に扱ってください。github等のパブリックスペースに公開すると悪用される可能性があります。 (今回の画像で使用した僕のAPIキーは念のため削除済みです。) 「キーの制限」から使用するAPIを指定できます。 実装コード APIを使用している部分 ↓ post.rb def get_sentiment require 'net/http' require 'uri' require 'json' # textに入れた文章が評価されます。 text = self.post # ENV["GOOGlE_API_KYE"]に取得したAPIキーを入れます。 uri = URI.parse("https://language.googleapis.com/v1beta1/documents:analyzeSentiment?key=#{ENV["GOOGlE_API_KYE"]}") request = Net::HTTP::Post.new(uri) request.content_type = "application/json" request.body = "" request.body = { document:{ type:'PLAIN_TEXT', content: text } }.to_json req_options = { use_ssl: uri.scheme == "https", } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end json = JSON.parse(response.body) # scoreに文章のポジティブ度が入ります。 score = json['documentSentiment']['score']*100 # magnitudeに文章の感情の強さみたいなものが入ります。 magnitude = json['documentSentiment']['magnitude']*100 sentiment = {score: score.to_i, magnitude: magnitude.to_i} end dotenv-rails等を使用して、ENV["GOOGlE_API_KYE"]に値を設定して使用。 最終的なコード  ↓ post.rb class Post < ApplicationRecord validates :post, presence: true, length: { minimum: 3, maximum: 20 } def set_sentiment_with_title sentiment = self.get_sentiment self.magnitude = sentiment[:magnitude] if sentiment[:score] > 50 title = ["ポンコツbaby", "ハッピー能天気バカ","so funy", "おしゃべりクソ野郎", "無駄話うそ太郎", "元気の押し売り", "言い訳クソメガネ", "ラッキー幸せ人間", "好感度おばけ"] self.sentiment = "ポジティブ" self.score = sentiment[:score] elsif sentiment[:score] > 0 title = ["おたんこなすび", "おまぬけ勘違いさん","おたんこなすび", "おしゃべりクソ野郎", "無駄話うそ太郎", "あほ", "言い訳クソメガネ", "クレイジー日本代表", "優しき偽善者"] self.sentiment = "ポジティブ" self.score = sentiment[:score] elsif sentiment[:score] >= -50 title = ["ポンコツbaby", "インテリくそ陰キャ","人間性皆無自己中人間", "おたんこなすび", "詐欺師", "ぴえん越えてぱおん", "だめだこりゃ", "元気出せよ?", "あほ"] self.sentiment = "ネガティブ" self.score = sentiment[:score]*-1 else title = ["ポンコツbaby", "インテリくそ陰キャ","人間性皆無自己中人間", "後ろ向きネガティブごみ人間", "ダイアモンド不愉快", "ぴえん越えてぱおん", "人間失格", "元気出せよ?", "堕天使"] self.sentiment = "ネガティブ" self.score = sentiment[:score]*-1 end self.personality_title = title[rand(10)-1] end def set_bournus return if self.random_int2 < 100 if self.personality2 == "香ばしさ" self.personality_title = "香ばしき漢" elsif self.personality2 == "神に愛され度" self.personality_title = "神に愛されし者" elsif self.personality2 == "尊さ" self.personality_title = "愛され地下アイドル" elsif self.personality2 == "足の臭さ" self.personality_title = "足クサおじさん" elsif self.personality2 == "強者の風格" self.personality_title = "範馬勇次郎" else self.personality_title = "パーリィーぴーぽー" end end def set_int_with_personality index1 = ["センス", "知性", "努力", "主人公度", "地頭力", "おもしろさ"] index2 = ["香ばしさ", "神に愛され度", "尊さ", "足の臭さ", "強者の風格", "人望"] self.random_int1 = rand(rand(200)) self.personality1 = index1[rand(7)-1] self.random_int2 = rand(rand(200)) self.personality2 = index2[rand(7)-1] end def get_sentiment require 'net/http' require 'uri' require 'json' text = self.post uri = URI.parse("https://language.googleapis.com/v1beta1/documents:analyzeSentiment?key=#{ENV["GOOGlE_API_KYE"]}") request = Net::HTTP::Post.new(uri) request.content_type = "application/json" request.body = "" request.body = { document:{ type:'PLAIN_TEXT', content: text } }.to_json req_options = { use_ssl: uri.scheme == "https", } response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http| http.request(request) end json = JSON.parse(response.body) score = json['documentSentiment']['score']*100 magnitude = json['documentSentiment']['magnitude']*100 sentiment = {score: score.to_i, magnitude: magnitude.to_i} end end hitokoto_controller.rb class HitokotoController < ApplicationController def new @post = Post.new end def create @post = Post.new(post_params) @post.set_sentiment_with_title @post.set_int_with_personality @post.set_bournus if @post.save redirect_to hitokoto_path(@post) else flash[:notice] = "ばぶばぶ(3文字以上20文字以下でちゅよ)" render "hitokoto/new" end end def index @posts = Post.all.limit(7).order(id: "DESC") end def show @post = Post.find(params[:id]) end def post_params params.require(:post).permit(:post) end end 設定した値を使って条件分岐によって、色々な値が出るように記述。 製作期間2〜3日の文字通りクソアプリです。 コントローラーの名前はちょっと失敗しています。可読性悪くて申し訳ないです。 公式の使用方法で実装した方が、APIからより詳細な値が帰ってきます。 https://cloud.google.com/natural-language/docs/quickstart-client-libraries?hl=ja 今回はgithubに公開しつつ、デプロイするという手順を時間をかけずに実装したため、簡易的な実装になっております。 アプリの詳細 viewを含めたコードはgithubに公開してます。 https://github.com/kosimaru1997/hitokoto 今回作成したクソアプリ https://ohitokoto.herokuapp.com/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]PrefixとURIパターンについて

ありがとうございます まずはじめにですが、 先ほど、過去に投稿したものについて、大変ありがたくご指摘いただきました。 返事の方法がイマイチわからず、改めて御礼申し上げます。 @shiozaki さんありがとうございます!勉強になりました! はじめに 本記事では、PrefixとURIパターンについて、説明いたします。 先日に、ルーティングネストでケアレスミスをし、 エラー対処に何時間と費やしてしまいました。 先日投稿したものも後ほどご覧ください。 改めて、詳しく説明したいと思い投稿します。 Prefixとは パスが入った変数のようなもので、 どのページに遷移したいかをパスとしてコードに記述する場合は、 末尾に「_path」を記載する必要があります。 URIパターン ルーティングのパスを表し、 このパスにてページに遷移した際に、指定のコントローラーとアクションで処理が実行されます。 ここにURIパターンに記載されているものは、遷移後のURLとほぼ同じです。 rails routesにて確認 例えですが、実際にrails routesしたものを添付します。 やや文字が小さいかもしれないです。すみません。 左から、 1番目:Prefix 2番目:HTTPメソッド 3番目:URIパターン 4番目:各テーブルのコントローラーとそれに対するアクションたち 使い方の例としては、 <%= link_to "by #{prototype.user.name}", user_path(prototype.user), class: "card__user" %> などと記述をします。 「user_path(prototype.user)」は、画像でいうところの一番下の行を使用しており、 一番右を見るとおり、「users#show」。 つまり、ユーザー情報ページに遷移するためのパスということになります。 ちなみに、適当なユーザー情報のページに遷移した場合、 URLは以下の通りになります。 http://localhost:3000/users/3 *「3」は3番目にユーザー登録したため、レコードにidが3となっており、「3」と表示されております。 ちなみに、users#showのURIパターンは、「/users/:id(.:format)」 URLの最後の記載とほぼ同じです。 また、 user_path(prototype.user)の(prototype.user)は、 誰のユーザー情報に遷移するのかを示すところになっています。 今回では、 「プロトタイプを投稿したユーザー(prototype.user)」の 「ユーザー情報に遷移user_path」するパス。ということです。 ルーティングネストによるケアレスミス 先日の投稿と内容はやや被ります。 resources :prototypes resources :prototypes do resources :comments, only: :create end resources :users, only: :show resources :prototypes resources :prototypes do resources :comments, only: :create resources :users, only: :show end この2つは、usersをネストしているか、していないかという違いです。 ネストしているかどうかでrails routesで記載されるものが違います。 つまり、ルーティングには気をつけろ!ということです。 終わりに ネストのミスについては、ルーティングのエラーの一つとして挙げられるのではないでしょうか。 今後も気をつけて学習を進めます。 また、はじめに書きましたが、 ご指摘をいただけるということは非常にありがたくと感じております。 右も左もわからず行動し投稿し始めたことによって学べることを今回身をもって知ることができました。 これからもやってみようと思った時から行動し、アウトプットを積極的に行うよう心がけます。 それでは、引き続きがんばります!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]フォロー、フォロワー機能

SNSの必須機能として、フォロー・フォロワー機能を実装していきます。 中間テーブルの理解が難しいとは思いますが、できるだけわかりやすく解説していきます。 開発環境 ruby 2.6.3 Rails 5.2.6 Bootstrap 4.5 前提 今回は、フォロー・フォロワー機能の実装のみの解説なので、deviseでユーザー認証が実装されている前提で話を進めていきます。 モデルコントローラーは以下 relationshipモデル relationshipsコントローラー 手順 モデルの作成 アソシエーション メソッド作成 コントローラー ビュー モデルの作成 まずは、Relationshipモデルを作成していきます。 RelationshipモデルはUserモデルの中間テーブルにあたります。 なぜなら、フォローするのもフォローされるのもユーザーなので、多 対 多の状態になるからです。 カラムは、 follower_id : フォローしたユーザー followed_id : フォローされたユーザー を準備します。 ユーザーのidで、user_idにしていないのがミソです。 Userモデルの中間テーブルになるため、どちらもユーザーのidが入るので、わかりやすいように、あえてuser_idを使っていません。 説明もこれぐらいにして、コマンド実行していきます。 $ rails g model Relationship follower_id:integer followed_id:integer $ rails db:migrate これで、Relationshipモデルができました。 follower_id : フォローしたユーザー followed_id : フォローされたユーザー カラム名がややこしくて、よくわからなくなるので、注意してください。 アソシエーション 中間テーブルは、このアソシエーションの理解が1番難しいです。 気合い入れてついてきてください! まず、関係性を整理しておきます。 1人のユーザーはたくさんのユーザーをフォローできる(1:N) 1人のユーザーはたくさんのユーザーにフォローされる(1:N) relationshipモデル 1人のユーザーはたくさんのユーザーにフォローもできるし、フォローもされるので、belongs_toでいきましょう。 models/relationship.rb class Relationship < ApplicationRecord # class_name: "User"でUserモデルを参照 belongs_to :follower, class_name: "User" belongs_to :followed, class_name: "User" end belongs_to :userちゃうの? と思いませんか? そうです。 本来、フォローしたユーザーとフォローされたユーザーは同じUserモデルから持ってきたいのですが、belongs_to :userとするとどっちがどっちのuserかわからなくなるので、followerとfollowedで分けています。 ただこのままだと、followerテーブルとfollowedテーブルを探しに行ってしまうので、class_name: "User"でuserテーブルからデータをとってきてもらうようにします。 userモデル では、続いてUser側のアソシエーションです。 models/user.rb # フォローをした、されたの関係 has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy # 一覧画面で使う has_many :followings, through: :relationships, source: :followed has_many :followers, through: :reverse_of_relationships, source: :follower まずは、フォローをした、されたの関係から見ていきます。 ここでは、relationshipsとreverse_of_relationshipsがありますが、さきほどと同じ考え方で、わかりにくいため名前をつけているだけです。 class_name: "Relationship"でRelationshipテーブルを参照します。 foreign_key(外侮キー)で参照するカラムを指定しています。 次に、フォロー・フォロワーの一覧画面で、user.followersという記述でフォロワーを表示したいので、throughでスルーするテーブル、sourceで参照するカラムを指定。 上の例では、reverse_of_relationshipsテーブルからfollower_idのデータを参照します。 メソッド作成 モデルにメソッドを記述していきます。 models/user.rb # フォローしたときの処理 def follow(user_id) relationships.create(followed_id: user_id) end # フォローを外すときの処理 def unfollow(user_id) relationships.find_by(followed_id: user_id).destroy end # フォローしているか判定 def following?(user) followings.include?(user) end これで、コントローラーをすっきりできます。 コントローラー まずはrelationshipsコントローラを作成します。 $ rails g controller relationships followings followers で、relationdhipsコントローラーに、createとdestroyアクションを追加します。 追加したらさきほどのメソッドを使って、コントローラーに記述していきます。 controllers/relationships_controller.rb class RelationshipsController < ApplicationController # フォローするとき def create current_user.follow(params[:user_id]) redirect_to request.referer end # フォロー外すとき def destroy current_user.unfollow(params[:user_id]) redirect_to request.referer end # フォロー一覧 def followings user = User.find(params[:user_id]) @users = user.followings end # フォロワー一覧 def followers user = User.find(params[:user_id]) @users = user.followers end end ルーティング コントローラーを作成したので、ルーティングも設定しておきます。 config/routes.rb # ネストさせる resources :users do resource :relationships, only: [:create, :destroy] get 'followings' => 'relationships#followings', as: 'followings' get 'followers' => 'relationships#followers', as: 'followers' end ビュー ビューではフォローボタンとフォロー、フォロワー一覧画面を別々で見ていきます。 フォローボタン ビューのどこでもお好きなところに配置してください。 お好きなところ <% if current_user.following?(user) %> <%= link_to "フォロー外す", user_relationships_path(user.id), method: :delete %> <% else %> <%= link_to "フォローする", user_relationships_path(user.id), method: :post %> <% end %> フォロー、フォロワー一覧画面 フォロー一覧もフォロワー一覧も同じ内容を表示するので、テンプレートをつくります。 views/relationships/_follow_list.html.erb <% if users.exists? %> <% users.each do |user| %> <table> <thead> <tr> <th>name</th> <th></th> <th></th> </tr> </thead> <tbody> <tr> <td><%= user.name %></td> <td>フォロー数: <%= user.followings.count %></td> <td>フォロワー数: <%= user.followers.count %></td> </tr> </tbody> </table> <% end %> <% else %> <p>ユーザーはいません</p> <% end %> で、このテンプレートをrenderで呼び出してくれればOKです! 今回のビューはあくまで、一例なので適宜変更してください。 まとめ 手順は以下 モデルの作成 アソシエーション メソッド作成 コントローラー ビュー 中間テーブルの理解が初心者にはなかなかキツイものがありましたが、ぼくでもこうやって記事にできるぐらいにまとめられたので、みなさんもきっと大丈夫だと思います。 特にアソシエーションの部分が難しいので、理解できるまで見返してみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gem bullet導入(N+1問題を分かりやすくするため)

なんで導入しようと思ったのか アプリケーションを作成中にN+1問題を可視化できるにして分かりやすくするような便利な機能ないかな~と探してみましたところタイトルのgemを見つけてこれは便利だと思いましたので、備忘録として使い方を記述していきたいと思います。 そもそもN+1問題って? Mysqlなどのデータベースからデータを読み込む際に余計にデータを読み込んでしまうことです。 分かりやすく例えるなら、商品を買おうと思ってレジにもっていったら一つ一つ商品をスキャンしていくイメージですね。 アプリケーションの動作がもっさりするなどの弊害があるため基本的にこの問題はなくしたほうが良いです。 導入 以下のコードをGemfileに記述すれば大丈夫です。 grop :development do Gem 'bullet' end あとはbundle installして下のコマンドを記述すれば準備は完了です bundle exec rails g bullet:install 公式テキストを見てみましたらどうやらほかにもいろいろと設定ができるらしいですか今回は省略します。 デフォルトで設定されている内容 上記のコマンドで、```config/environments/↑上記のコマンドで、config/environments/development.rbにデフォルトで以下の様なコードが追加されました。 development.rb Rails.application.configure do # ここから config.after_initialize do Bullet.enable = true Bullet.alert = true Bullet.bullet_logger = true Bullet.console = true # Bullet.growl = true デフォルトでコメントアウトされてる Bullet.rails_logger = true Bullet.add_footer = true end # ここまでが追加される。以下、同ファイルにもとから入っていた内容は省略 end bulletの詳細な設定項目一覧←こちらにて各項目の設定内容についての確認ができます。 以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby on rails] 改行の反映 form_withで入力

やりたいこと 改行も反映させたい!!!!! 現状 form-withで改行して入力しても、 反映されない! <div class="form-group"> <%= f.label :introduction,"自己紹介" %><br /> <%= f.text_area :introduction, autofocus: true,class:"form-control" %> </div> <div class="col-md-8 ml-5" style="margin-top:1em;"> <h6>Introduction</h6> <p><%= user.introduction %></p> </div> 改善後 こう書くと、改行される!!! safe_joinの部分です。 <div class="col-md-8 ml-5" style="margin-top:1em;"> <h6>Introduction</h6> <p><%=safe_join(user.introduction.split("\n"),tag(:br)) %></p> </div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTTPステータスコード

HTTPステータスコードとは HTTPレスポンスと一緒に返ってくる番号のこと。 HTTPメソッドで通信が行われる時必ずステータスコードと一緒にレスポンスが 返される。 重要!! これはおさえましょう。 200   正常です。 オッケーです。 400  リクエストに誤りがあります。確認してください 404 そんなものありません。 見つかりません 500 ごめんなさい。 サービス側のミスです。 知っておいて損はない 204 特にデータとして返すものがありません 302  リダイレクトします。(別のページに飛びます。) 304 キャッシュ使ってます。 401 認証できないので見せられません 403 アクセス権がない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails エラーメッセージ・フラッシュメッセージ

記事投稿画面 posts/new.html.erb <%@posts.errors.full_messages each do |message|%>・・1 <%=message%>・・エラーメッセージを表示 <textarea><%=@post.content%></textarea>・・直前の投稿内容を表示 ・・1配列@posts.errors.full_messagesから要素を一つずつ取り出して変数messageに代入 *注意点 newアクションで@postが定義されないとエラーになる Userモデルの作成 カラム名:name データ型:stringであるUserモデルの作成 $rails g model User name:string email:string 投稿が空のときにエラーメッセージはどうなるのかターミナルで確認 $rails console //コンソール(入力・出力の機能を備えた装置の機能)の起動 >post=Post.new(content:")//contentが空であるPostインスタンスの作成 >post.errors.full_messages =>[] //保存失敗前にはからの配列が入っている >post.save =>false //作成したPostインスタンスをPostテーブルに保存=>失敗 >post.errors.full_messages =>[contentを入力してください]//保存失敗後にはエラーメッセージの配列が入っている フラッシュメッセージ フラッシュメッセージ・・ページ上に一度だけ表示されるページ アクションで変数flash[:notice]に文字列を代入すると、flash[:notice]をビューで使える。 <%if flash[:notice]%>フラッシュメッセージが存在するときのみ表示
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails バリデーション

バリデーション バリデーションとは・・不正なデータがデータベースに保存されないようにデータベースをチェックする仕組み。バリデーションに引っかかった場合(不正なデータの場合)にはデータベースには保存されない。 バリデーションの例 Postモデルのバリデーション models/post.rb class Post<ApplicationRecord validates :content,{presence:true} #検証するカラム名   検証する内容 end =>contentカラムが存在しているか models/user.rb class User<ApplicationRecord validates :email,{uniqueness:true} #検証するカラム名   検証する内容 end =>emailで新たにユーザー登録できないようにするためにemailの重複がないか
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactを使用したRailsアプリをRspecで統合テストする方法

はじめに この記事では, React(react-rails)を使用したRailsアプリの統合テストをする方法について書いています. RSpecで統合テストを書こうとした際に色々ハマったポイントがあるので, そこを重点的に解説します. 【動作環境】 Rails 6.1.4 RSpec 3.10 1. ひとまず書いてみる まず他の記事などを参考にCapybaraというgemをインストールします. これによりユーザーがブラウザで行うような操作をCapybaraのメソッドで実行することができます. 統合テストで重宝するgemのようです. spec/features/signup.rb gem 'capybara', '>= 2.15' 早速, featureというフォルダの中に統合テストファイルを作成し, topページに行ってアカウント登録ボタンを押す操作を書きます 以下のvisitやclick_buttonなどがCapybaraのメソッドになります. spec/features/signup.rb require 'rails_helper' feature "Signup" do example "新規登録後にユーザーページが表示される" do visit "/" click_button "新規アカウント登録" end end 統合テストデビューに歓喜し意気揚々とでbundle exec rspecを実行すると以下のエラーが. Failures: 1) Signup 新規登録後にユーザーページが表示される Failure/Error: click_button("新規アカウント登録") Capybara::ElementNotFound: Unable to find button "新規アカウント登録" that is not disabled # ./spec/features/user_spec.rb:6:in `block (2 levels) in <top (required)>' 指定された"新規アカウント登録"なんてbuttonタグないけど?と怒られています. いやあるでしょ? こっちはchromeの検証機能使ってあるのを確認してるんですが? いろいろ調べたところ, 純粋なRailsアプリであればこれで動くようですが, 今回はReactを導入したことが原因で動きません. 2. :js => true が必要 解決するには, 以下のように「:js => true」を追記してやります. これを書かないとjsファイルが読み込まれず, Reactのコンポーネントが描画されないようです. spec/features/signup.rb require 'rails_helper' + feature "Signup", :js => true do - feature "Signup" do example "新規登録後にユーザーページが表示される" do visit "/" click_button "新規アカウント登録" end end これでreactのcomponentも描画されるようになりました. 3. selenium-webdriver が必要 もう一度, ターミナルでbundle exec rspecを実行してみると今度は以下のエラーが出ます. Failures: 1) Signup 新規登録後にユーザーページが表示される Failure/Error: visit "/" LoadError: Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler. 「Capybaraのselenium driverはselenium-webdriverを読み込めないので, gem 'selenium-webdriver'をインストールしてください」と教えてくれています. その通りにgemを追加しbundle installします. Gemfile group :test do gem 'capybara', '>= 2.15' + gem 'selenium-webdriver' gem 'rspec-rails' gem "factory_bot_rails" gem 'faker' end 4. Firefoxをダウンロード 3度目の正直で, ターミナルでbundle exec rspecを実行してください. 無事以下のエラーが出ます. Failures: 1) Signup 新規登録後にユーザーページが表示される Failure/Error: visit "/" Selenium::WebDriver::Error::WebDriverError: Could not find Firefox binary (os=macosx). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path= 言われた通りにFirefoxをダウンロードします. $ brew install --appdir="/Applications" firefox もう一度, ターミナルでbundle exec rspecを叩きますが, 以下のエラー. Failures: 1) Signup 新規登録後にユーザーページが表示される Failure/Error: visit "/" Selenium::WebDriver::Error::WebDriverError: Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver. 以下で解決します. $ brew install geckodriver 以上で テストが通るようになりました. これで, bundle exec rspecを叩くとfirefoxが起動して実際にブラウザの操作をしてくれます.お疲れ様でした. 5. 新規登録Formに値を入力し, 登録ボタンを押すまで あとは以下のようにCapybaraを使って統合テストを書いていくだけです. ここでは新規登録Formに値を入力し登録ボタンを押しています. なお, 今回はReactによってSPA化しているため正しいページにリダイレクトされているか確認するコードは含まれていません. spec/features/signup.rb require 'rails_helper' feature "Signup" , :js => true do example "新規登録後にユーザーページが表示される" do visit "/" click_button("新規アカウント登録") fill_in 'user_name', with:'test_user' fill_in 'email', with:'hogehoge@hoge.com' fill_in 'password', with:'password' fill_in 'password_confirm', with:'password' click_button("登録") end end 最後に 私は原因がわからず解決に2時間ほどハマってしまいました. この記事によって少しでも救われる人がいれば幸いです.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsで架空のCafeのHPを作ってみよう!【15日目】『1以上の半角数字の正規表現』編

概要 基本Railsの記法に則り書いていきます! 1から全ての説明ではなく その中であれ?どうやるの?と 疑問に思った点や実装に困った箇所を ピックアップして紹介していきます♩ 設定と準備 ・Rails ・HTML ・CSS ・Javascript(jQuery) ↑上記の言語とフレームワークを使い 架空(自分で考えたテキトーなもの)のCafeの HPを作っていこうと思います! 15日目の作業内容 ・JQueryを使いエラーメッセージを非同期で表示 15日目の気になった箇所 値段の入力で1以上の半角数字で入力させるエラーメッセージを記述したい。 仮説 正規表現を使い半角数字かつ1以上のマッチした時以外でエラーメッセージを 出せば表現できるはず。 今回は正規表現の箇所だけ抜粋して仮説と結論を記述するので エラーメッセージの表示のさせ方などは割愛させていただきます。 error_messages.js if (price.match(/^[0]+[^0-9]/)){ $('#price-error').html('1以上かつ半角数字で入力してください'); } return result; } このように ^ ← 先頭の1文字のマッチする  [0]  ← 数字の0 [^0-9] ← 半角数字以外 先頭が0かつ半角数字以外にマッチするような正規表現で試したが うまくいかなかった。 先頭が0だとダメなのでこの記述だと先頭は文字列を含んでしまい "a" などを 入力しても通ってしまう。 逆にして error_messages.js if (price.match(/[^0-9]+^[0]/)){ $('#price-error').html('1以上かつ半角数字で入力してください'); } return result; } このように半角数字かつ先頭が0だとダメという正規表現を試してみたが 先頭を意味する ^ ←こちらは最初に記述する必要があるため機能しなかった。 結論 分けて段階を踏み、マッチさせていく必要があった。 error_messages.js if (price.match(/[^0-9]/)){ $('#price-error').html('半角数字で入力してください'); } else if (price.match(/^[0]/)){ $('#price-error').html('1以上でお願い致します'); } return result; } このように段階を踏みまずは、 /[^0-9]/ ← 半角英数字のみ その次に、 /^[0]/ ← 先頭が0だとダメ という風に、大きな枠から順に狭めていくように 記述するとうまく記述することができる!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails 投稿編集・更新画面

記事編集画面 config/routes.rb get"posts/:id/edit"=>"posts#edit" posts/1/editというURLが送信されたときに、postsコントローラーのeditアクションが実行される posts/edit.html.erb <%=link_to("編集”,"/posts/#{@post.id}/edit")%> 「編集」をクリックすると、URLが/posts/id/editのページに移動 posts_controller.rb def edit @post=Post.find_by(id: params[:id]) end postsコントローラーのeditアクションにおいて、idがURLで入力された値の投稿データを変数@postに代入した。 投稿更新画面 updateアクション=>フォームの内容への保存・投稿一覧画面への転送 posts/edit.html.erb <%= form_tag("/posts/#{@post.id}/update") do %> <textarea name="content"><%= @post.content %></textarea> <input type="submit" value="保存"> <% end %> 保存ボタンをクリックすると、フォームに入力された内容がURL"posts/#{@post.id}/updateに送信される。 posts_controller.rb def update @post = Post.find_by(id: params[:id])・・1 @post.content = params[:content]・・2 @post.save・・3 redirect_to('/posts/index') end しかし、updateアクションに対応するビューがないので、URL"/posts/index"に転送する。 ・・1idがURLで入力した値の投稿データを変数@postに代入した。 ・・2カラム名がcontentで、そのcontentがname属性で指定したフォームに入力されたデータで変数@post.contentに代入した。 ・・3作成したPostインスタンスをPostテーブルに保存。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

deviseによるgmail認証、本番環境への適用

概要 本記事では、Ruby on RailsのGem「devise」を用いて、ユーザー新規登録機能を実装していきます。 本番環境でメール認証が適用できない点で詰まったので、本番環境での設定方法まで解説していきます。 本記事でやること Gmail認証を使ったユーザー新規登録方法 Gmail側の設定 メール内容をカスタマイズ 本番環境でもGmail認証が使えるようにする 環境 バックエンド Ruby 2.6.5 Rails 6.0.3 Gem devise devise-i18n dotenv-rails データベース MySQL 5.7 参考にした記事 【Rails備忘録】deviseまとめ Deviseでログイン機能を追加・日本語化・Bootstrap4適用まで deviseを使ったログイン機能を実装する!メール認証機能付き 【Rails】deviseでURL認証付きのメールを送信してみる 完成した後の動作 ①ユーザー新規登録画面で、情報を入力 ②入力したメールアドレス宛にメールが送信されるフラッシュが表示 ③Gmailを確認して、メールが届いていることを確認、メール内リンクをクリック ④メール認証が完了し、ログインが可能となる 補足 メール内のリンクをクリックしないと本人確認をするフラッシュが表示され、ログインができない仕様 アカウント確認メールを再送することも可能(本記事に実装方法記載していません) 前提 RailsのMVCなど基本を理解されていること Railsアプリケーションを新規作成済みであること deviseがインストール済みであること Gmailアカウントを作成済みであること 実装(準備編) マイグレーションを以下の様な構成にして、マイグレーションを実行してください 補足 - メール認証のみであれば、Confirmableの箇所のみコメントアウトすれば良いが、パスワードリセットやログイン情報保持をする場合は、以下のようにRecoverable、Rememberableの箇所もコメントアウトしてください。 20200627035125_devise_create_users.rb # frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.0] 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 deviseの機能が使えるようuser.rbに以下を記載 app/models/user.rb devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :lockable, :timeoutable, :trackable 新規登録時のエラーメッセージなどを日本語化させましょう 以下の様な構成になります config/locales/devise.views.ja.yml ja: activerecord: attributes: user: ~~省略~~ devise: confirmations: confirmed: メールアドレスが確認できました。 new: resend_confirmation_instructions: アカウント確認メール再送 send_instructions: アカウントの有効化について数分以内にメールでご連絡します。 send_paranoid_instructions: メールアドレスが登録済みの場合、本人確認用のメールが数分以内に送信されます。             ~~省略~~ mailer: confirmation_instructions: action: メールアドレスの確認 greeting: "%{recipient}様" instruction: 以下のリンクをクリックし、メールアドレスの確認手続を完了させてください。 subject: "アカウントの有効化のご案内"              ~~省略~~ shared: links: back: 戻る didn_t_receive_confirmation_instructions: アカウント確認のメールを受け取っていませんか? didn_t_receive_unlock_instructions: アカウントの凍結解除方法のメールを受け取っていませんか? forgot_your_password: パスワードを忘れましたか? sign_in: ログイン sign_in_with_provider: "%{provider}でログイン" sign_up: 新規登録 minimum_password_length: "(6~20桁の半角英数字)"              ~~省略~~ Gmail側の設定をします。 ①Gmailにログインし、2段階認証はオンにしてください ②アプリパスワードの生成 Gmail → 設定 → アカウント → セキュリティ → アプリパスワード → パスワードを入力 → アプリを「その他」に設定し、「現在作成しているアプリケーション名」 → 生成 → 以下の画面になると思いますので、必ずメモしてください!(アプリパスワードは再生成できません) Gmailでメールを受け取れるようにする設定にします(開発環境) config/enviroments/development.rb config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address:"smtp.gmail.com", domain: 'gmail.com', port:587, user_name: Rails.application.credentials.gmail[:user_name], password: Rails.application.credentials.gmail[:password], authentication: :login } 重要 GitHubにuser_nameとpasswordを記載するのは危険なため、credentialで保存してください! 以下のコマンドを実行 terminal EDITOR=vim rails credentials:edit INSERTにして、以下を記入したら:wqで抜ける vim gmail: user_name: Gmailアドレス password: 先ほど生成したアプリパスワード ここまできたら一度Githubにプッシュしましょう 実装(Mailer編) デフォルトのMailer設定を変更,送信元メールアドレスを変更 以下の様な構成にします。 補足 config.confirm_withinでURLの有効期限が設定できます config/initializers/devise.rb Devise.setup do |config| config.mailer = 'Users::Mailer' config.mailer_sender = '認証メール<〇〇〇〇〇〇@gmail.com>' require 'devise/orm/active_record' config.reconfirmable = true config.expire_all_remember_me_on_sign_out = true config.password_length = 6..20 config.timeout_in = 1.day config.confirm_within = 1.days config.reset_password_within = 6.hours config.scoped_views = true config.sign_out_via = :delete end Mailer自体をオーバーライド app/mailers/users/mailer.rb class Users::Mailer < Devise::Mailer helper :application include Devise::Controllers::UrlHelpers default template_path: 'devise/mailer' def confirmation_instructions(record, token, opts={}) if record.unconfirmed_email != nil opts[:subject] = "認証を行ってメールアドレス変更手続きを完了してください" else opts[:subject] = "認証を行ってユーザ登録を完了してください" end super end end 実装(MVC作成編) Viewは以下の様な構成にします。 補足 - if文をフォームの下に設置することにより、バリデーションエラーが以下に表示される様になります。 - cssクラスはご自身で設定されているものに変更してください。 app/views/devise/registrations/new.html.erb <section class="login"> <div class="login__imgBx"> <%= image_tag 'introduction.jpg' %> </div> <div class="login__contentBx"> <div class="login__formBx"> <div class="login__title">新規登録</div> <%= form_with model: @user, url: user_registration_path, id: 'new_user', class: 'new_user', local: true do |f| %> <div class="login__inputBx"> <%= f.label :name, {class: 'login__label'} %> <%= f.text_field :name, maxlength: '50' %> <% if @user.errors.include?(:name) %> <p class="login__form-error"><%= @user.errors.full_messages_for(:name).first %> <% end %> </div> <div class="login__inputBx"> <%= f.label :email, {class: 'login__label'} %> <%= f.email_field :email, maxlength: '100 '%> <% if @user.errors.include?(:email) %> <p class="login__form-error"><%= @user.errors.full_messages_for(:email).first %> <% end %> </div> <div class="login__inputBx"> <%= f.label :password, {class: 'login__label'} %> <%= f.password_field :password, autocomplete: "off", minlength: @minimum_password_length, maxlength: '20' %> <% if @minimum_password_length %> <small class="form-text text-muted"><%= t('devise.shared.minimum_password_length', count: @minimum_password_length) %></small> <% end %> <% if @user.errors.include?(:password) %> <p class="login__form-error"><%= @user.errors.full_messages_for(:password).first %> <% end %> </div> <div class="login__inputBx"> <%= f.label :password_confirmation, {class: 'login__label'} %> <%= f.password_field :password_confirmation, autocomplete: "off", minlength: @minimum_password_length, maxlength: '20' %> <% if @user.errors.include?(:password_confirmation) %> <p class="login__form-error"><%= @user.errors.full_messages_for(:password_confirmation).first %> <% end %> </div> <div class="login__inputBx"> <%= f.submit "新規登録" %> </div> <% end %> <%= render 'devise/shared/links' %> </div> </div> </section> controllerは以下の様な構成にします。(newとcreateアクションをオーバーライドします。) app/controllers/users/registrations_controller.rb # frozen_string_literal: true class Users::RegistrationsController < Devise::RegistrationsController def new super @user = User.new end def create @user = User.new(user_params) if @user.save flash[:notice] = "ユーザー認証メールを送信いたしました。認証が完了しましたらログインをお願いいたします。" redirect_to new_user_session_path else flash[:alert] = "ユーザー登録に失敗しました。" render action: :new and return end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end メール内容のカスタマイズ app/views/devise/mailer/confirmation_instructions.html.erb を作成 作成後以下の様な構成にします。 補足 登録済みの方が、再度アカウント確認をした場合を想定して、条件分岐で内容を切り替えています。 app/views/devise/mailer/confirmation_instructions.html.erb <div><%= @user.name %>様</div> <div>〇〇〇〇〇〇〇をご利用いただきありがとうございます。</div> <% if @user.try(:unconfirmed_email?) %> <div>以下のリンクからユーザの認証を行ってメールアドレス変更手続きを完了してください。</div> <div><%= link_to 'ユーザ認証を実行する', confirmation_url(@user,confirmation_token: @token) %></div> <% else %> <% if @user.confirmed_at != nil %> <div>会員登録が完了済みです。</div> <div>下記リンクからログインをお願いいたします。</div> <p>http://localhost:3000/</p> <% else %> <div>以下のリンクからユーザの認証を行ってユーザ登録を完了してください。</div> <div><%= link_to 'ユーザ認証を実行する', confirmation_url(@user,confirmation_token: @token) %></div> <div> このURLの有効期限は24時間です。</div> <% end %> <% end %> ここで開発環境でGmailに認証メールが届くか確認しましょう。 確認できたらGithubにプッシュしましょう 実装(本番環境編) production.rbに認証メール送信で必要なことがあります。 以下の様な構成になります。 補足 ドメイン名を設定してあげないと、本番環境ではGmailに認証メールが届かないため設定しましょう。 環境変数でGmailアドレスやアプリパスワードを渡す必要があるため、dotenv-rails Gemをインストールし、環境変数を.envファイルに記載しましょう config/environments/production.rb Rails.application.configure do ~~省略~~ config.action_mailer.perform_caching = false config.action_mailer.default_url_options = { host: 'アプリケーションのドメイン名'} config.action_mailer.perform_deliveries = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address:"smtp.gmail.com", domain: 'gmail.com', port:587, user_name: ENV['SEND_MAIL'], password: ENV['GMAIL_SPECIFIC_PASSWORD'], authentication: :login, openssl_verify_mode: 'none', enable_starttls_auto: true } config.action_mailer.perform_caching = false config.action_mailer.raise_delivery_errors = true ~~省略~~ end 環境変数の設定は以下の様になります。 .env SEND_MAIL="Gmailアドレス" GMAIL_SPECIFIC_PASSWORD="生成したアプリパスワード" 環境変数はGithubにあげるのは危険なため、.gitignoreファイルに.envを追加しましょう .gitignore ~~省略~~ .env Githubにプッシュしします これで、本番環境でメール認証が飛んでいるはずです。 苦労した点 Gmailアドレスとアプリパスワードの設定することに気づかず、詰まりました。 本番環境でメールが飛ばない事態が発生しており、本番環境用のMailer設定については記事が少なく大変でしたが、設定できました。 まとめ deviseはブラックボックスなところが多く、大変ですが、Qiitaを参考に実際に手を動かして、試行錯誤すると、便利な部分はデフォルトでカスタマイズしたいところはカスタマイズできるのでこちらの記事を参考に皆さんのポートフォリオ作りの糧になればと思います。 ご質問などがありましたらコメントいただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Permission denied - connect(2) for app_root/tmp/sockets/puma.sock (Errno::EACCES)の解決法【Puma】【Rails】

環境 WSL2 問題 $ bundle exec puma したらタイトルのようなエラーが出てpumaを起動できなかった。ディレクトリのパーミッションを変更しても変わらず... 解決策 結果的にrbenv-sudoでソケットファイルを生成して開けた。 $ git clone git://github.com/dcarley/rbenv-sudo.git ~/.rbenv/plugins/rbenv-sudo $ rbenv sudo bundle exec puma ただこのままCtrl+Cで離脱してしまうとpuma.sockが消えてしまい、 毎回rbenv-sudoしなくてはいけないのでプロセスを強制終了する。 別ターミナルでプロセスを検索して $ ps aux | grep puma root 5983 0.6 4.2 1266260 129268 ? Sl 12:43 0:09 puma 5.2.2 強制終了。 $ kill 5983 これでpuma.sockが残留するので $ ls tmp/sockets/ puma.sock $ bundle exec puma で開けるようになる。完
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on RailsでCRUD処理をしてみる

Railsの学習を始めるにあたって、基本的な動作である、CRUD処理を学習してみた。現段階の理解度を確認する意味を込めてCRUD処理とActive Recordについてひも解いてみる。 目次 1.守破離の「守」一番大事な基礎であるCRUD処理の勉強。 2.Active Recordとお友達になる。 3.CRUD処理を噛み砕く 4.まとめ 5.参考文献 1. 守破離の「守」一番大事な基礎であるCRUD処理の勉強。 まず、Railsガイドを読みながら理解を深めた。 Active Record の基礎 - Railsガイド 中でもmodelでテーブルが作られる仕組みは、全然頭に入ってこない。 2. Active Recordとお友達になる。 Active RecordがRailsのMVCに置けるMの役割を果たしているそうだ。 Railsガイドによると、その中でも重要な機能を抜粋すると以下の5つになる。 モデルおよびモデル内のデータを表現する モデル同士の関連付け(アソシエーション)を表現する 関連付けられているモデル間の継承階層を表現する データをデータベースで永続化する前にバリデーション(検証)を行なう データベースをオブジェクト指向スタイルで操作する 正直言ってよく分からない。今理解できていることを下記にまとめてみた。 モデル名は単数、テーブルのカラム名は複数かつキャメルケースで表示される。 モデルの中にテーブルを作成し、その中に属性を入れ込んでいく。 モデルの作成 $ bin/rails g model Genba name:string description:text g modelコマンドを実行することで生成されるクラス。 class CreateGenbas < ActiveRecord::Migration[] def change create table :genbas do |t| t.string :name t.text :description t.timestamps end end end ); これで、以下のようにテーブルに格納する項目を追加することができる p = Genba.new p.name = "Some Book" puts p.name # "Some Book" 3. CRUD処理を噛み砕く Create 登録機能 def create genba = Genba.new(genba_params)#=>privateを呼び出している genba.save! redirect_to genbas_url, notice: "タスク「#{genba.name}を登録しました。"#=>登録したらrootURLにリダイレクトされる end private def genba_params params.require(:genba).permit(:name, :description)#=>:nameと:descriptionのみ許可している end .container - if flash.notice.present? .alert.alert-success= flash.notice #=>これでcreateアクションが完了した時にflashが発行される。 Read 一覧表示機能 def index @genbas = Genba.all end この時はまだSQL文は発行されていない。viewで@genbas.each doのように呼び出された時に初めて SQL文が実行される。 index.html.slim - @genbas.each do |genba| tr td= genba.name td= genba.created_at こうすることでViewで一覧を表示することができる。 Show 検索機能 def show @genba = Genba.find(params[:id]) end findはidによってモデルオブジェクトに対応するレコードをDBから検索している。 引数としてparams[:id]を設定している。 params[:id]には、リクエストされたURL"genbas/[タスクのid]"の[タスクのid]の部分が格納されている。 Update 更新機能 model def update genba = Genba.find(params[:id]) genba.update!(genba_params) redirect_to genbas_url, notice: 'タスク「#genba.name」を更新しました。' end view Edit 編集機能 def edit @genba = Genba.find(params[:id]) end = link_to '編集する', edit_genba_path(genba), class: 'btn btn-primary mr-3' Delete 削除機能 model def destroy genba = Genba.find(params[:id]) genba.destroy redirect_to genbas_url, notice: "タスク「#{genba.name}」を削除しました" end view = link_to '削除', genba, method: :delete, date: { confirm: "タスク「#{genba.name}」を削除します。よろしいですか?} ,class: 'btn btn-danger' Partialを使用したモデルの設定方法 view = render partial: 'form', **locals: {genba: @genba} #=>「インスタンス変数@genbaをパーシャル内のローカル変数genbaをして渡す」** _form.html.slim =form_with model: genba, local: true do |f| .form-group = f.label :name = f.text_field :description, class: 'form-control', id:'genba_description' 4. まとめ 簡単な掲示板アプリの作成に必要な考えを学べた。 C 作成処理 R 一覧表示やホーム画面表示 U 更新処理 D 削除処理 次はルーティングに関して勉強したい。 5. 参考文献
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【独学・未経験】Ruby on Rails, AWS, Docker, CircleCIでポートフォリオを作成

ポートフォリオ紹介 アプリ名: BookLike Github: https://github.com/tera487/book_like 概要 BookLikeは、本の気づきを共有、発見するSNSアプリです。 開発背景 大学生になってから、ビジネス本や自己啓発本を読むようになりました。本を読むことで、新しい発見やさまざまな考えを知ることができましたが、本を読んでもその本の知識を日常生活に生かしきれていませんでした。このことから、本の知識を自分の知識として吸収し、日常生活で活用することで読書をする意味があると思いました。 そこで本の内容をアウトプットすることで、「本の知識が定着し、日常生活に生かしやすいのでは?」と考えました。そして本の感想や気づきをアウトプットし、また他人の感想から新たな学びが生まれると思い、『BookLike』を開発しようと思いました。 使用技術 フロントエンド HTML/CSS JavaScript(jQuery) Bootstarp 5.0 バックエンド Ruby 2.6.6 Rails 6.1.4 Mysql 8.0.25 開発環境 Docker/Docker-compose MySQL 5.7 本番環境 AWS(VPC、EC2、RDS for MySQL、S3、ALB、 IAM、Route53) MySQL 5.7 CircleCI (CI/CD) その他 Rubocop(コード整形) Rspec(単体・統合テスト) レスポンシブ化 お名前.com(独自ドメインの取得) 実装機能 ユーザー関連 新規登録機能・登録情報編集機能(画像登録可能) ログイン機能 ゲストログイン機能 フォロー機能(非同期) 管理者関連 管理者情報編集機能 記事投稿・編集・削除 アカウント削除 投稿関連 新規投稿・編集・削除 いいね機能(非同期) 通報機能(非同期) 書籍関連 書籍検索機能(楽天APIの利用) 読んだ本一覧 ER図 インフラ構成図 工夫した点 UI/UX 本を読んでいる人にも読んでいない人に、手軽に使ってもらいたいと思い、簡単に使ってもらうにはどのように設計していけばいいか考えながら作成しました。 モダンな技術の使用 自動デプロイ 開発環境にDockerを使用 AWSにデプロイ CircleCIでCI/CDパイプラインの構築 今後の技術的課題 本番環境でのDockerコンテナの利用(ECS) Terraformでインフラをコード化 SPAでの開発(vue.js React) 反省点 ポートフォリオ作成 完璧に理解してからポートフォリオを作成しようと思い、技術書を購入し、繰り返し勉強をしていたため、ポートフォリオ作成が遅れてしまいました。ポートフォリオを作成することで、あいまいに覚えているところの復習や自分がわからないところがわかるようになると思います。なので、基本的な知識を身につけたらポートフォリオの情報収集・作成すべきだと思いました。 エラー対応 エラーをしてからの対応が良くなかったと思います。エラー内容を理解せずに、Googleにエラー文をコピーしてエラーを解決しようとしていました。そのため、余計に時間がかかることがありました。まず何がエラーをおこしているか確認し、エラーしている意味を理解してから、それに対しての対応を模索することがエラー解決の近道であると考えます。 最後に 最後までご覧いただき、ありがとうございました。 ポートフォリオを作成してみて、改めて自分はプログラミングが好きだと思いました。まだ実力不足ですが自分が考えたものが形になるのが面白いと思いました。今後は反省点を活かし、プログラミングに励んでいきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新規登録・ログイン画面実装① devise 新規登録の項目追加 

deviseで、新規登録画面、ログイン画面を実装しました。 その際にnameカラムと、入社何年目かの等級(年齢層?社歴?)を追加するカラムも追加しましたので、備忘録として残します。 カラムの追加 class DeviseCreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| ## Database authenticatable # メールアドレスでユーザー登録 t.string :email, null: false, default: "" # パスワードも必須 t.string :encrypted_password, null: false, default: "" 省略〜〜〜 t.timestamps null: false # 名前を登録してもらう t.string:name,null:false # 社歴?を登録 t.string:join_year,null:false 省略〜〜〜 まずは保存する用のカラムを追加します。stringで問題ないのか若干不安です。 ApplicationControllerの記述 class ApplicationController < ActionController::Base # ユーザー認証などが行われる前に、configure~が実行される before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters # デフォルトにないname/join_yearを追加しているので、それらを許可するよう記載している devise_parameter_sanitizer.permit(:sign_up, keys: [:name,:join_year]) end end (:sign_up, keys: [:name,:join_year])にはemailは入りません。デフォルで入ってるようです。 新規登録画面の編集 <div class="form-group"> <%= f.label :name,"お名前" %><br /> <%= f.text_field :name, autofocus: true,class:"form-control" %> </div> デフォルトで入ってるので省略 <div class="form-group"> <%= f.label :join_year,"クラス" %><br /> <%= f.select :join_year,[["1年目", "1年目"], ["2年目", "2年目"], ["3年目", "3年目"],["4年目", "4年目"],["5年以上", "5年目"]], include_blank: "選択して下さい",class:"form-control" %> </div> 終わり 追々、グレードアップしていきます。 現在の疑問点・・string型で大丈夫なのか。 参考にした記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Capybara

Capybaraとは? WebブラウザとWebアプリケーションの間で交わされるHTTP通信をエミュレート(模倣)するためのライブラリです。 mkdir spec/features/ _spec.rb spec/featuresに配置する。 使用方法 require 'rails_helper' RSpec.feature 'ログインとログアウト' do background do # ユーザを作成する User.create!(email: 'foo@example.com', password: '123456') end scenario 'ログインする' do # トップページを開く visit root_path # ログインフォームにEmailとパスワードを入力する fill_in 'メールアドレス', with: 'foo@example.com' fill_in 'パスワード', with: '123456' # ログインボタンをクリックする click_on 'ログイン' # ログインに成功したことを検証する expect(page).to have_content 'ログインしました' end end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】enumを使ってステータス管理をしよう!

対象者 商品等ののステータス管理を実装予定の方 セレクトタグを実装予定の方 目的 ステータスで進捗や状況を管理できるような機能を実装する 実際の手順と実例 1.前提 ケーキ屋さんのECサイトを作成しています。 ここでは注文ステータスを取り扱うので、モデル名「order」、カラム名「order_status」とします。 管理者が注文ステータスを操作できるようにしたいので、 2.カラム追加 まずは対象のモデル(order)にカラムを追加していきます $ rails g migration AddOrderStatusToOrder order_status:integer enum(イーナム)で数字管理していくのでデータ型はintegerで与えます。 3.モデルにenumを追記 以下の通り書いていきます。 order.rb enum order_status: { "入金待ち":0, "入金確認":1, "製作中":2, "発送準備中":3, "発送済":4 } 番号が0から始まっている点に注意です。 表示したい内容とそれに合わせて数字を順に並べていきます。 4.Viewで表示 今回は、管理者が操作して保存できるようにしたいので、 form_withを使って内容を保存できるように更新ボタンも付けます orders/show.html.erb <%= form_with model: @order, url: admin_order_path, method: :patch, local: true do |f| %> <%= f.select :order_status, Order.order_statuses.keys, class: "order_status" %> <%= f.submit "更新" , class: "btn btn-outline-success" %> <% end %> @order = Order.find(params[:id])とControllerに定義しています。また、ストロングぱらめーたーにも、permitでorder_statusを入力しています。 これで実装完了です。 参照 【Rails】enumを使ってステータス管理を行う 【Rails】enumを使用したセレクトボックスの実装とDBへの保存 投稿者コメント プログラミングスクールで勉強学んだことをそのままアウトプットしてみました。今後も7月に開発したものの中からどんどん発信していきます! My Profile プログラミング学習歴②ヶ月目のアカウントです! プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。 また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。 もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ActiveRecordのデータを暗号化しよう

active_record_encryptionというgemを使う 誰でも簡単3ステップで導入 ①gemを導入 Gemfileに以下を追記 gem 'active_record_encryption' bundle install ②カラムを設定 blob型でカラムを設定します。例えばユーザーの本名、生年月日を暗号化するならこんな感じ class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" t.string :uid, null: false t.string :nickname, null: false t.blob :first_name, null: false t.blob :last_name, null: false t.blob :first_name_kana, null: false t.blob :last_name_kana, null: false t.blob :birth_date, null: false t.references :organization, foreign_key: true ③モデルに暗号化したカラムの元データを定義 モデルに以下のように記載します。 encrypted_attribute(:first_name, :string, default: "") encrypted_attribute(:last_name, :string, default: "") encrypted_attribute(:first_name_kana, :string, default: "") encrypted_attribute(:last_name_kana, :string, default: "") encrypted_attribute(:birth_date, :date) ④暗号化方式を定義 config/initializers/active_record_encryption.rbに以下のように記述します。 暗号化key、saltについては知られちゃまずいので環境変数で設定します。 ActiveRecordEncryption.default_encryption = { encryptor: :active_support, key: ENV['ENCRYPTION_KEY'], salt: ENV['ENCRYPTION_SALT'] } ⑤DBにデータを保存する この状態でDBにデータを保存するとこんな感じの値が入ります。 見た目はなんのこっちゃわからないのですが、値を取り出すとちゃんと保存時に指定した値が取り出せます。 [2] pry(main)> user.first_name => "山田" 感想 結構簡単に実装できてしまうのでセキュリティ的にどうなの?って感じもする。 SQLインジェクションとかで値を抜き取られたときとかに強そう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む