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

RailsでJaveScriptが動かないときの原因と対処法

はじめに Railsでアプリケーション製作中、jsを思うように動かせず苦労したため、躓いたポイントをまとめました。 初学者のため基礎的な内容かと思いますが、どなたかの参考になると嬉しいです! 前提条件 Rails 5.x.x jQuery 3.x.x app/assets/javascripts/ 以下のファイルにjsを記述していることを前提とします。 原因1 そもそもJavaScript、jQueryが読み込まれていない まずは基本的なところを確認します。 ビューにスクリプトを読み込むための記述があるか application.html.erb <head> 〜省略〜 <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> gemが追加されているか Gemfile gem 'jquery-rails' → bundle installを実行 application.jsファイルにJQueryを読み込むための記述があるか application.js //= require jquery3 //= require jquery_ujs //= require_tree . //= require jquery と //= require jquery_ujs は //= require_tree . より上に書く必要があります。 //= require_tree .は javascriptsディレクトリ配下のjsファイルを出力に含めるという記述なので、順番を逆にしてしまうとjQueryを読み込む前にjsファイルに記述した内容が読み込まれてしまいます。 原因2 turbolinksの影響 turbolinksとは、高速化を目的としたライブラリで、rails4以上ではデフォルトで入っています。 ページ遷移をAjaxに置き換え、画面の一部だけを更新することで高速化しようとするため、ページ読み込みを起点としたjsのイベントが発火しなくなってしまいます。 リンクを経ずに直接ページにアクセスしたり、ページをリロードした場合にはturbolinksの影響を受けないため、正常に動作します。 リンクを踏んでページ遷移した際にもjsを動作させるには下記の方法で記述します。 turbolinks:loadとすることで初回読み込み、リロード、ページ切り替えの全てで処理を実行できるようになります。 xxxx.js $(document).on('turbolinks:load', function() { 実行したい処理 }); また、リンクに下記記述をすることで特定のリンクのみturbolinksを無効化することができますが、ユーザビリティを考えるとあまり多用しない方が良いのかな...? <%= link_to "turbolinksの無効化", root_path, 'data-turbolinks': false %> 原因3 エラーが出て処理が止まっている 記述は上から順に読み込まれ、エラーが出た時点で止まってしまうため、該当部分の記述が正しくても、それより上に記述した部分でエラーが出ていると処理が実行されません。 エラー部分を修正することで正常に動作するようになります。 原因4 指定した要素を見つけられていない getElementById('hoge')などで要素を取得し、その要素に対しての処理を記述していた場合、#hogeを取得できないと当然その後の処理は実行できません。 考えられる原因としては HTMLより先にJSが読み込まれている そもそもそのページに指定した要素がない などがあるかと思います。 前者の場合、処理を下記関数内に入れてあげるとページを読み込んでから処理を実行できるようになります。 xxxx.js window.onload = function () { 実行したい処理; }; 後者の場合は、スペルミスの他、意図しないページでイベントが発火していることも考えられます。 //= require_tree . の記述をしているため、処理を実行させたいページ以外でもjsの記述が読み込まれています。 ページ読み込みをトリガーとしている場合などはイベントが発火してしまい、指定した要素を探しに行ってしまいます。 対処法は色々あると思いますが、一つの例として「要素がない場合は処理を終了する」という条件文を追加することで、続く処理でのエラーを防ぐことができます。 xxxx.js function(){ if (!document.getElementById("hoge")) return //この文を追加 '#hoge'に対する処理; }; まとめ RailsでJaveScriptが動かないときの原因と対処法 そもそもJavaScript、jQueryが読み込まれていない turbolinksの影響 エラーが出て処理が止まっている 指定した要素を見つけられていない Railsでjsを動作させるにあたって躓いたところ、調べたことをアウトプットさせていただきました。間違っている箇所がありましたらご指摘いただけると嬉しいです?‍♀️ 参考 Rails5でjqueryを動かす方法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2にRailsアプリをデプロイ③ ~本番環境にデータベースを用意する~

はじめに これは前回の続きです。 データベースを本番環境に用意してあげてデータを保存できるようにします。 私はローカル環境でMySQLを利用してアプリケーションの作成をしました。 MariaDBをインストール MariaDBとはMySQLの派生として開発されているオープンソースソフトウェアです。今回使用しているAmazon Linux 2ではこのMariaDBを使用することとなっており、MySQLと互換性があります。 下記のコマンドでインストールします。 Amazon Linux 2を利用している場合yumコマンドでインストールできます。 ターミナル [ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install mariadb-server mysql-devel systemctlコマンドというコマンドを使ってインストールしたソフトウェアを起動します。 ターミナル [ec2-user@ip-172-31-25-189 ~]$ sudo systemctl start mariadb 起動しているかの確認を下記のコマンドで行います。 ターミナル [ec2-user@ip-172-31-25-189 ~]$ sudo systemctl status mariadb ● mariadb.service - MariaDB database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled) Active: active (running) since 土 2020-02-29 07:00:11 UTC; 7s ago Process: 5993 ExecStartPost=/usr/libexec/mariadb-wait-ready $MAINPID (code=exited, status=0/SUCCESS) Process: 5957 ExecStartPre=/usr/libexec/mariadb-prepare-db-dir %n (code=exited, status=0/SUCCESS) 緑色で「acrtive(running)」と表示されていれば起動できています。 データベースのrootパスワードの設定をします。 yumでインストールしたMariaDBはデフォルトでrootというユーザーでアクセスできるようになっています。しかしパスワードが設定されていないので自分で設定する必要があります。 このパスワードは後ほど使うのでメモに残しておいてください。 私はメモを残していなくて大変苦労しました!! 下記のコマンドを実行しパスワードを設定します。 ターミナル [ec2-user@ip-172-31-25-189 ~]$ sudo /usr/bin/mysql_secure_installation 実行したあと ①Enter current password for root (enter for none): 」と表示されたらEnterキーを押します。 ②「Set root password? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す ③「New password:」と表示されたら自身で決めたパスワードを入力 ※入力しても特に変化ありませんが文字はちゃんと入力されています ④「Re-enter new password:」と表示されたら、同じパスワードを入力 ※入力しても特に変化ありませんが文字はちゃんと入力されています ⑤ ①〜④が完了したあとは細かい質問を4つほどされるので全て「Y」を入力してエンターしてください。 最後にちゃんとパスワードが使えるか確認をしてみます。下記コマンドを入力 ターミナル [ec2-user@ip-172-31-25-189 ~]$ mysql -u root -p 「Enter password:」と表示されたら先ほどのパスワードを入力してエンターを押します。 下記ように表示されればしっかり設定できています。 ターミナル Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 142 Server version: 5.5.64-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> 「exit」を入力したら閉じられます。 これでデータベースを用意できました。 次回はいよいよデプロイしていきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

find_byメソッドとparamsの使い方

find_byの使い方がよくわかっていないので復習がてらここに記載していきたいと思います。 find_byを使うと指定したデータを受け取ることができる。 たとえば、 モデル名.find_by(カラム名: 値) とすることでその値を持ったデータベースからデータを受け取ることができる。 find_byを使うと指定したデータを受け取ることができることを覚えておきたい。 paramsの使い方は2通りあって ① 「:○○」を使ったルーティングのURLから値を取得できる。 ① get "posts/:○○ => ... ② 「name="○○"」が付いたフォームの入力内容を取得できる。 ②
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

モデルの作成、カラムの追加・削除の仕方 [Ruby on Rails]

モデル作成 terminal $ rails generate model [モデル名] [属性名:データ型 属性名:データ型・・・] [オプション] $ rails generate model User name:string email:string #最後忘れずに更新 $ rails db:migrate コマンドを実行すると以下の4つが自動生成されます。 ・モデルのクラスファイル ・マイグレーションファイル ・モデルの自動テスト ・モデルの自動テストで使うfictureファイル カラムの追加 terminal $ rails g migration Addカラム名Toモデル名 カラム名:データ型 $ rails generate migration AddNicknameToUsers nickname:string #最後忘れずに更新 $ rails db:migrate カラムの削除 terminal $ rails generate migration Removeカラム名Fromモデル名 カラム名:データ型 $ rails generate migration RemoveNameFromUsers name:string #最後忘れずに更新 $ rails db:migrate 引用 : Rails /テーブル作成、カラムの追加や削除[備忘録]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

モデルの作成・削除、カラムの追加・削除の仕方 [Ruby on Rails]

データベース、テーブル、カラム、レコードの意味 この画像にないモデルは、テータベースの設計図であり、テーブルの総称と考えていいでしょう。 引用 : Railsにおけるモデルについて モデル(テーブル)の作成 terminal $ rails generate model [モデル名] [カラム名:データ型 カラム名:データ型・・・] [オプション] $ rails generate model User name:string email:string #最後忘れずに更新 $ rails db:migrate コマンドを実行すると以下の4つが自動生成されます。 ・モデルのクラスファイル ・マイグレーションファイル ・モデルの自動テスト ・モデルの自動テストで使うfictureファイル データ型の種類 string : 文字列 text : 長い文字列 integer : 整数 decimal : 小数 datetime : 日時 binary : バイナリデータ boolean : Boolean モデル(テーブル)の削除 terminal $ rails destroy model [モデル名] $ rails destroy model User #最後忘れずに更新 $ rails db:migrate カラムの追加 terminal #モデル名が複数形 $ rails g migration Addカラム名Toモデル名s カラム名:データ型 $ rails generate migration AddNicknameToUsers nickname:string #最後忘れずに更新 $ rails db:migrate カラムの削除 terminal #モデル名が複数形 $ rails generate migration Removeカラム名Fromモデル名s カラム名:データ型 $ rails generate migration RemoveNameFromUsers name:string #最後忘れずに更新 $ rails db:migrate 引用 : Rails /テーブル作成、カラムの追加や削除[備忘録]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人開発】食品催事イベント投稿サイト「Saizy」を作りました!

はじめに 転職活動とプログラミングの勉強のため、 食品催事イベント専用の投稿サイト「Saizy」を作りました! 名前は催事(さいじ)から取って、Saizy(サイジー)です! ネーミングセンスがなくてすいません。。。 Saizy| 美味しいスイーツ、和菓子、惣菜などの催事情報サイト | Saizy テストアカウント email: test@example.com password: password 作ろうと思ったきっかけ 現職で催事関連の方達と接することが多く、 コロナで催事出店も少なくなっている中、 ITの世界では、催事に関してのサービスがほぼない状態です。 みなさま、インスタグラムや出店場所のHPにちょこっと掲載されていることが多く、 一つにまとめたサイトがあればいいのになと思ったことがきっかけです。 使いかた ログインしていなくても、催事の情報をみることができます。 ログインしていただければ、 催事の投稿、いいね、口コミ投稿をすることができます。 投稿画面は簡素なデザインにしました。 出店場所に施設名「新宿駅」などと入力していただくと、 詳細画面に自然と、Googlemapsで指定した場所が表示されます。 レスポンシブ アプリを作っていく中で、 通勤時間や、寝る前などスマホでちゃんと動いているかを確認したかったので、 レスポンシブデザインも最低限実装しました。 HTML、CSSは1から書いています! 最後に アプリを作っていく中で、 どうやったら、こんな実装ができるのか、どうやって調べたらいいのか等、 自分の頭で考え、調べることが多くなりました! 周りにエンジニアがいなかったため、 教えてもらったりなどできなかったのですが、 teratailで助けてくれた方、Qiitaやブログで情報発信ている方のおかげで、 アプリを作ることができました!ありがとうございす! 1日エラーで終わってしまった様な日もありましたが、 毎日、知らないことが頭に入っていく感じがとても楽しかったです! 今回のアプリは修正点がかなりあるかと思いますので、 ご指摘等いただければ大変ありがたいです! 今後は、エンジニアへの転職活動を始めつつ、 いろいろな方が役に立つなーと思ってもらえる様なアプリを作りたいと思っています。 お忙しい中、最後までご覧いただきありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsセキュアパスワードの実装について

セキュアパスワードとは セキュアパスワードという手法を使う際には、 ユーザーにパスワードとパスワードの確認の入力をさせ、 そのままDB上に保存するのではなくハッシュ化したものを DBに保存する方法のことを指します。 セキュアパスワード使用されるハッシュ化の処理は、 入力されたデータをハッシュ関数を使用して 元のデータに戻すことのできない(不可逆)形にする処理を行なっています。 ユーザー認証は、「パスワードの送信」→「ハッシュ化」→「DB内のハッシュ化された値との比較」といったような手順で進んで行きます。 比較した結果が一致すれば、送信したパスワード(入力したパスワード)は正しいということになり、ユーザー認証されることになります。 仮にDBの内容が盗まれたり、覗き見られるようなことがあってもパスワードの安全性が保たれ、 生のパスワードをデータベースに保存することなく認証することができます。 セキュアパスワードの実装方法 モデルファイルにhas_secure_passwordメソッドを追加 modelにhas_secure_passwordを追加します。 models/user.rb class User < ApplicationRecord has_secure_password end モデルにhas_secure_passwordを追加することで、下記のような機能が使えるようになります。 ハッシュ化したパスワードを、データベース内の「password_digest」という属性に保存することができるようになる 2つのペアの仮想的な属性「password」、「password_confirmation」が使用できるようになり、存在性と値が一致するかどうかのバリデーションも追加される *(モデルのオブジェクトからは存在しているように見えるが、データベースには対応するカラムが存在しない、という意味です。) authenticateメソッドが使えるようになる has_secure_password機能は記述するだけで使用可能になりますが、 モデル内に「password_digest」という属性が存在している必要があります。 password_digestをテーブルに追加 コンソールから、属性名と型の情報を入力していきます。 $ rails generate migration add_password_digest_to_users password_digest:string [timestamp]_add_password_digest_to_users.rb class AddPasswordDigestToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :password_digest, :string end end エラー等がなければ、マイグレーションを実行します。 $ rails db:migrate bcryptをinstall has_secure_passwordを使ってパスワードをハッシュ化するためには、最先端のハッシュ関数であるbcryptが必要になります bcryptを使うためにGemfileに追加します。 Gemfile gem 'bcrypt', '3.1.13' bundle install
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails db:migrate時のエラー「Cannot add a NOT NULL column」について

初めに 某ガイドの学習中にエラーが発生したため、その解決方法を記事にします。 初めての投稿ですので、至らぬ点などあればご指摘いただけますと幸いです。 エラーが発生した状況 UserテーブルとTaskテーブルがあります。 User : Taskの間で1 : 多の関係となるように、マイグレーションファイルを作成し、マイグレーションを行ったタイミングで下記エラーが発生しました。 発生したエラー terminal rails aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "tasks" ADD "user_id" integer NOT NULL エラー内容を見てみると「Cannot add a NOT NULL column with default value」と記載があるとおり、columnにNOT NULLを与えることができないとなっています。 エラーが発生した際のマイグレーションファイルは以下のとおりです。 xxxxxxxxxxxxxx_AddUserIdTasks.rb class AddUserIdToTasks < ActiveRecord::Migration[5.2] def up execute "DELETE FROM tasks;" add_reference :tasks, :user, null: false, index: true end end execute "DELETE FROM tasks;"はSQLによって、ここまでに作成したタスクを削除しています。 add_reference :tasks, :user, null: false, index: trueでは、tasksにuserと関連付けたuser_idカラムを追加し、制約としてnull: false, index: trueオプションをつけようとしています。 このadd_reference行についてエラーが発生しました。 解決した方法 先にも記載したとおり「Cannot add a NOT NULL column with default value」ということでしたので、null: falseを削除したら無事マイグレーションできました。 xxxxxxxxxxxxxx_AddUserIdTasks.rb class AddUserIdToTasks < ActiveRecord::Migration[5.2] def up execute "DELETE FROM tasks;" add_reference :tasks, :user, index: true end end 原因について詳しく特定できていませんが、某ガイドの指定しているデータベースとは別のデータベースを用いているのが理由なのかなと考えています。試していないので断言はできませんが。。。 なお、下記を行うことでNOT NULL制約を与えることができました。 xxxxxxxxxxxxxx_ChangeUserIdToTasks class ChangeUserIdToTasks < ActiveRecord::Migration[5.2] def change change_column :tasks, :user_id, :integer, null: false end end 参考にさせて頂いた記事 [Qiita]マイグレショーンファイルを作成する際のnull: false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsプロジェクトのデータベースの構造のER図をPlantUMLで自動的に吐き出せるようにしてみた

モチベーション QiitaでもPlantUMLを表示できるようになってきたので、いよいよPlantUMLが民主化されてきました。 そこで「データベースの情報を基に自動的にER図作ってくれたらいいのになぁ...」と思ったので勢いで作ってみました。 対象となる技術の選定と制限 ER図の特徴の都合上、各種リレーションの定義を取得するためにはORMが使用されているものを対象に作成する必要があります。 今回は以下が使用されている環境を想定してスクリプトを作成・実行しました MySQL Rails これは実行テストを行った対象である 「ハッカソンの開催情報を自動でお知らせするBot HackathonPortal 」 の実行環境に合わせたためです。 同じ Rails でも Postgresql や SQLite においては実行確認していないのでうまくいくかわかりません。(試してみてうまくいったご報告をいただけましたら幸いです。その時は更新いたします) 実際に作成したソースコード 以下が実際に作成したコードになります task export_entity_relationship_diagram_plantuml: :environment do # 使用されている全てのテーブルのModelの情報を取得するために全て読み込む Rails.application.eager_load! # 使用されている全てのテーブルを持っていて関係性がわかるModelの情報を取得する model_classes = ActiveRecord::Base.descendants.select{|m| m.table_name.present? } class_name_model_class_pair = model_classes.index_by(&:to_s) relation_entity_components = Set.new entity_component_fields = Set.new foreign_key_pairs = {} # ER図においてそれぞれのエンティティとの関連性を記述していく class_name_model_class_pair.values.each do |model_class| model_class.reflections.values.each do |relation_info| # polymorphic の belongs_to の構造はリレーション関係がわからないのでスルー next if relation_info.polymorphic? # belongs_to 参照元を取得する場合はfrom と toの対象を交換する if relation_info.instance_of?(ActiveRecord::Reflection::BelongsToReflection) to_model_class = model_class from_model_class = class_name_model_class_pair[relation_info.class_name] else from_model_class = model_class to_model_class = class_name_model_class_pair[relation_info.class_name] end primary_keys = [from_model_class.primary_key].flatten to_foreign_key_string = [to_model_class.table_name, relation_info.foreign_key].join(".") if relation_info.options[:primary_key].present? from_foreign_key_string = [from_model_class.table_name, relation_info.options[:primary_key]].join(".") else from_foreign_key_string = primary_keys.map{ |primary_key| [from_model_class.table_name, primary_key].join(".") }.join(",") end # 外部キーのカラムとの関係性を記録する foreign_key_pairs[to_foreign_key_string] = from_foreign_key_string # has_many 関係性を表現 1対多の場合 if relation_info.instance_of?(ActiveRecord::Reflection::HasManyReflection) # 0 ~ 複数 relation_entity_components << [from_model_class.table_name, "--o{", to_model_class.table_name].join(" ") # has_one 関係性を表現 1対1の場合 elsif relation_info.instance_of?(ActiveRecord::Reflection::HasOneReflection) # belongs_toの要素が先に登録されていたら消す relation_entity_components.delete([from_model_class.table_name, "--o{", to_model_class.table_name].join(" ")) # 0 ~ 1 relation_entity_components << [from_model_class.table_name, "|o--o|", to_model_class.table_name].join(" ") # has_many :through 関係性を表現 多対多の場合 elsif relation_info.instance_of?(ActiveRecord::Reflection::ThroughReflection) relation_entity_components << [from_model_class.table_name, "}o--o{", to_model_class.table_name].join(" ") # belongs_to 参照元を取得 とりあえず 1対多として記録 elsif relation_info.instance_of?(ActiveRecord::Reflection::BelongsToReflection) # has_one の要素が記録されていたらスキップ unless relation_entity_components.include?([from_model_class.table_name, "|o--o|", to_model_class.table_name].join(" ")) relation_entity_components << [from_model_class.table_name, "--o{", to_model_class.table_name].join(" ") end end end end # ER図においてそれぞれのエンティティのカラムの特徴を記述していく class_name_model_class_pair.values.each do |model_class| primary_keys = [model_class.primary_key].flatten entity_components = [] entity_components << ['entity', '"' + model_class.table_name + '"', '{'].join(" ") model_class.columns.each do |model_column| table_column_string = [model_class.table_name , model_column.name].join(".") if primary_keys.include?(model_column.name) entity_components << ["+", model_column.name, "[PK]", model_column.sql_type].join(" ") entity_components << "==" # 外部キーには目印 elsif foreign_key_pairs[table_column_string].present? entity_components << ["#", model_column.name, "[FK(" + foreign_key_pairs[table_column_string] + ")]", model_column.sql_type].join(" ") else entity_components << [model_column.name, model_column.sql_type].join(" ") end end entity_components << '}' entity_components << "\n" entity_component_fields << entity_components.join("\n") end # PlantUMLを記述 plntuml_components = Set.new plntuml_components << "```plantuml" plntuml_components << "@startuml" plntuml_components += entity_component_fields plntuml_components += relation_entity_components plntuml_components << "@enduml" plntuml_components << "```" export_plantuml_path = Rails.root.join("er-diagram.plantuml") File.write(export_plantuml_path, plntuml_components.to_a.join("\n")) end 上記のソースコードを rails runner または rake task名, rails task名 にて実行することで、プロジェクト内のER図を表したPlantUMLファイルが出力されます 実行テスト 上記のスクリプトを実行して のプロジェクトのER図を出力してみた内容が以下の通りになります ER図を輩出してみたことで、使用していないテーブルやポリモーフィックの多様などデータ構造におけるアンチパターンを多用していることが判明したので、本プロジェクトについては後日テーブル構造を見直そうと思います... また HackathonPortal のプロジェクトやソースコードはこちらにて公開していますので興味がある方はこちらも参照してください。 処理の中身の解説などはこちらを参照してください 最新のハッカソンの開催情報を自動で集めて、お知らせするBotを作ったので頭の中を紹介 まだフォローしていない方はフォローのほどよろしくお願いします。 @HackathonPortal これから 希望が多くありましたら、汎用的に使用できるように gem化 しようと思います。 また勢いで作ったので汎用化にあたり漏れているユースケースがあるかもしれません。 その場合は都度更新していきたいと思います。 参考 PlantUMLでER図を書いて、githubで管理してみた やさしい図解で学ぶ ER図 表記法一覧
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】コメント削除機能の実装(備忘録)

はじめに アプリ開発中に、コメント削除すると古い順から削除されてしまう状況から、更にエラーになり詰まってしまったので、教えて頂いたことも含め備忘録としてまとめます。 開発環境 Mac Ruby 2.7.2 Rails 6.1.3.2 前提条件 コメント投稿機能は実装済み Articleモデル(投稿) Commentモデル(コメント) 現状 コメント削除をすると、古い順から削除される現状。 該当コード config/routes.rb resources :articles do resource :comments, only: %i[create destroy] end app/controllers/articles_controller.rb def show @comment = Comment.new @comments = Comment.includes(:user, :article).order(created_at: :desc) end app/controllers/comments_controller.rb class CommentsController < ApplicationController def create article = Article.find(params[:article_id]) @comment = current_user.comments.build(comment_params) @comment.article_id = article.id if @comment.save flash[:notice] = 'コメントしました' redirect_back(fallback_location: root_path) else flash[:alert] = 'コメントできませんでした' redirect_back(fallback_location: root_path) end end def destroy current_user.comments.find_by(article_id: params[:article_id]).destroy! flash[:alert] = '削除しました' redirect_back(fallback_location: root_path) end private def comment_params params.require(:comment).permit(:content).merge(user_id: current_user.id, article_id: params[:article_id]) end app/views/articles/show.html.erb <div> <h2>コメント</h2> <%= render "comments/form" %> <%= render "comments/comment" %> </div> app/views/comments/_comment.html.erb <% @comments.each do |comment| %> <hr> <p><%=link_to "#{comment.user.name}", user_path(comment.user.id) %></p> <p><%= comment.content %></p> <p><%= link_to "削除", article_comments_path(@article, comment), method: :delete, data: { confirm: "削除しますか?" } %></p> <% end %> app/views/comments/_form.html.erb <%= form_with(model: [@article, @comment], local: true) do |form| %> <%= form.text_area :content %> <%= button_tag type: "submit", class: "btn btn-success float-right mt-1" do %> <i class="far fa-comments"></i> コメントする <% end %> <% end %> 原因 app/controllers/comments_controller.rbのfind_byメソッドが原因で、古い順から削除されていました。 app/controllers/comments_controller.rb def destroy current_user.comments.⭐find_by(article_id: params[:article_id]).destroy! flash[:alert] = '削除しました' redirect_back(fallback_location: root_path) end find_byメソッドとは? 各モデルをid以外の条件で検索するメソッド(idでも検索可能。複数の検索条件を指定可能)。返ってくる結果は、最初にヒットした1件のみ!(ココ大事。) id及びid以外の条件が分かっている場合、その条件に該当する最初のデータを取得したい場合に使用。該当データがない場合は、nil が返る。 最初にヒットした1件のみなので、指定したコメントを削除できない状況になっていました。 解決法 find_by ではなく、 find へ変更。 app/controllers/comments_controller.rb def destroy current_user.comments.⭐find(article_id: params[:article_id]).destroy! flash[:alert] = '削除しました' redirect_back(fallback_location: root_path) end 解決〜!と思っていたら、下記のエラー発生。「コメントのidがみつかりません」と表示されています。binding.pry 使用して、確認すると、comment_idがnill となっていました。 Couldn't find Comment with 'id'={:article_id=>"5"} [WHERE "comments"."user_id" = $1] なぜ?nil になるのか? 基本的に findメソッド は、プライマリーキー項目しか引数に取れない。(正確に言うと、引数に取れるが find で取得する対象は自動的に id という項目のみ。) comment_id というカラムは存在しないため、nil になる。 上記のアドバイスを頂いて、なるほど~!となりました。 (article_id: params[:article_id]) を下記の⭐へ変更 app/controllers/comments_controller.rb def destroy current_user.comments.find(⭐params[:id]).destroy! flash[:alert] = '削除しました' redirect_back(fallback_location: root_path) end 今度は、idがnil とのエラーになりました。 ActiveRecord::RecordNotFound (Couldn't find Comment with 'id'={:id=>nil} [WHERE "comments"."user_id" = $1]): View側に、idを設定していないので、「idがありませんよ」と怒られていると仮定して、下記へ変更。 app/views/comments/_comment.html.erb <p><%= link_to "削除", article_comment_path(⭐comment.article.id, comment.id), method: :delete, data: { confirm: "削除しますか?" } %></p> 次こそ上手くいく!と思っていましたが、下記エラー。「ルートが一致しません。」と怒られます。ルートの記述が間違っていると仮定。 ActionController::RoutingError (No route matches [DELETE] "/articles/5/comments.206"): resource から resources へ変更。 routes.rb ⭐resources :comments, only: %i[create destroy] resourceメソッド には、idが付与されないため、リソースを絞り込めない(絞り込まない)状況で使用するもの。 かなりの凡ミスです 複数存在するリソース(商品やユーザーなど)では resources を使用しましょう。 これで、無事に指定したコメントの削除が可能になりました! まとめ 基本的なメソッドの理解がなく、ハマってしまったエラーでした。今回のエラーで、基本的なメソッドを復習できて大変勉強になりました。同じようなエラーにハマっている方へ、参考になると幸いです 参考記事 [Rails]コメント削除機能の実装でハマってしまったので一応解決策を。 指定先のコメント削除ができない Railsガイド
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【第8章】Railsチュートリアルでハッシュとシンボルについて忘れていたので復習した

Railsチュートリアル第8章(第6版)でハッシュとシンボルを忘れていたので、復習した。 ①ハッシュとは ・基本的には配列と同じだが、インデックスとして整数値以外のものを使える。 ・キーと値のペアを波カッコで囲んで表記する。 ・ハッシュでは要素の並び順が保障されない。 ・JavaでいうMapだと思っている。 >> user = {} # {}は空のハッシュ => {} >> user["first_name"] = "Pai" # キーが "first_name" で値が "Pai" => "Pai" >> user["last_name"] = "Abble" # キーが "last_name" で値が "Abble" => "Abble" >> user["first_name"] # 要素へのアクセスは配列の場合と似ている => "Pai" ②省略1 ハッシュの1要素を角カッコを使って定義する代わりに、=>(ハッシュロケット)を使ってリテラル表記する方が簡単。 >> user = { "first_name" => "Pai", "last_name" => "Abble" } => {"last_name"=>"Abble", "first_name"=>"Pai"} ③省略2 -シンボル- ・Railsではハッシュのキーとして、文字列よりもシンボルを使うのが普通。 ・シンボルはクォートで囲む代わりにコロンを前に置く。 ・文字列と違って全ての文字が使えるわけではない。(一般的なアルファベットを使うかぎりは問題ないらしい) ・Ruby以外ではごく一部の言語にしか採用されていない特殊なデータ形式。 >> "name" #文字列 => "name" >> :name #シンボル => :name >> :foo-bar              #使えない文字 NameError: undefined local variable or method `bar' for main:Object >> :2foo #使えない文字 SyntaxError ハッシュのキーにシンボルを採用する場合のuser >> user = { :first_name => "Pai", :last_name => "Abble" } => {:last_name =>"Abble", :first_name =>"Pai"} ④省略3 ハッシュではシンボルをキーとして扱うことが一般的なので、Ruby1.9からは新しい記法がサポートされた。 ・シンボルとハッシュロケットの組み合わせを、キーの名前の前ではなく後にコロンを置き、その後に値が続くように置き換えることが出来る。 >> user = { first_name: "Pai", last_name: "Abble" } => {:last_name =>"Abble", :first_name =>"Pai"} ⑤まとめ ①~④で忘れていた箇所を思い出せた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails 6】 テーブルへCSVファイルをインポートした際にNameErrorが出力された時の対処法

はじめに CSVファイルをテーブルにインポートした際に、NameErrorが出力されて躓いたので、備忘録として残します。 開発環境 Mac Ruby 2.7.2 Rails 6.1.3.1 PostgreSQL 13.2 前提 rails db:seedコマンドを実行後、以下のseeds.rbからimport_csv.rbを呼び出して、テーブルにcsvファイルをインポートします。 db/seeds.rb ImportCsv.information_data lib/autoloads/import_csv.rb class ImportCsv # CSVデータのパスを引数として受け取り、インポート処理を実行 def self.import(path) list = [] CSV.foreach(path, headers: true) do |row| list << row.to_h end list end def self.information_data list = import('db/csv_data/information.csv') puts "インポート処理を開始" Information.create!(list) puts "インポート完了!" end end エラーメッセージ 前提で記載した通り、rails db:seedを実行した結果、以下のエラーメッセージが出力されました。 % rails db:seed rails aborted! NameError: uninitialized constant ImportCsv NameErrorのメッセージ内容を調べてみましたところ、以下の記事によると、NameErrorは定義されていない変数またはメソッドを使用したときに発生するとのことです。 seeds.rbからimport_csv.rbを上手く呼び出せていないのでは?と思いました。 対応方法 以下のようにapplication.rb(すべての環境で共通の設定ファイル)のconfig.autoload_paths(オートロード対象)にlib/autoloadsを指定することで、import_csv.rbを呼び出すようにしました。 config/application.rb module モジュール名 class Application < Rails::Application # lib/autoloads ディレクトリ配下のファイルを読み込む config.autoload_paths << Rails.root.join('lib/autoloads') end end 上記の設定後にrails db:seedを実行してみた結果、テーブルにCSVファイルを上手くインポートすることができました。 % rails db:seed インポート処理を開始 インポート完了! % 参考記事 エラーメッセージから学ぶ Railsドキュメント_設定ファイルについて Railsドキュメント_オートロード対象となるパスの追加
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[RSpec]system specでコントローラーのテスト(FactoryBot使用)

今回はRSpecの中トロ部分、system specでコントローラーのテストを実行していきます。 コントローラーのテストでは、実際に操作するような感覚でテストコードを書いていきます。 開発環境 ruby 2.6.3 Rails 5.2.6 前提 FactoryBot使用 Faker使用 capybara使用 devise使用 RSpecの準備、FactoryBotでのテストデータの定義等は、下記記事にまとめてますので、まだの方は先にこちらをどうぞ。 [Rails]RSpecでテストを行う準備(FactoryBot使用) ファイルの作成 まずは、spec配下にsystemフォルダを作って、その中に各コントローラーのファイルを作っていきます。 今回は、 posts_spec.rb を例にコードを記述していきます。 作成した各モデルのファイルで、rails_helperの設定を読み込んでいきます。 rails_helperはRSpecの設定が記述してあるファイルです。 コードを1行書くだけで、読み込めるので先に記述しておきます。 最初にまとめて書いておくことで、書き忘れを防げます! コントローラーファイル require 'rails_helper' deviseのヘルパーを使えるようにする controllerのテストを実行していく中で、sign_inなどのdeviseのヘルパーを使う機会が出てきます。 なぜRSpecのコードを書いていくときに、deviseのヘルパーが必要かというと、アクセス権限でログインしてないユーザーを許可していない場合があるからです。 ユーザーの編集ページはログインしてないときは、アクセスできないなど spec/rails_helper.rbにdeviseのヘルパーを使えるようにコードを追加します。 spec/rails_helper.rb : # deviseのヘルパーメソッドをsystemで使用できるように設定 config.include Devise::Test::IntegrationHelpers, type: :system end これでdeviseのヘルパーをsystemで使用できるようになりました。 capybaraの設定 systemでCapybaraを使ってテストできるように、spec_helperに設定を追加します。 spec/spec_helper.rb : RSpec.configure do |config| # 以下3行を追加 config.before(:each, type: :system) do driven_by :rack_test end : これでsystemでcapybaraが使えるようになりました。 テストコードを書いていく posts_specでは投稿のテストと削除のテストを行います。 テスト項目の洗い出し まずはテスト項目の洗い出しを行っていきます。 投稿のテストでは、成功したときと失敗したときのテストを書いていきます。 spec/system/posts_spec.rb require 'rails_helper' describe '投稿に関するテスト' do describe "投稿のテスト" do context "投稿が成功したとき" do it "投稿成功後の遷移先が正しいか" do # この中にテストの処理を書いていく end it "投稿成功後の表示の確認" do # この中にテストの処理を書いていく end end context "投稿が失敗したとき" do it "投稿失敗後の遷移先が正しいか" do # この中にテストの処理を書いていく end it "投稿失敗後の表示の確認" do # この中にテストの処理を書いていく end end end describe "削除のテスト" do it "削除リンクが表示されているか" do # この中にテストの処理を書いていく end it "削除されるか" do # この中にテストの処理を書いていく end end end RSpecの記述の基本形がわからない方はこちらの記事参照 最低限覚えておきたいRSpecの基本構成 テストデータをつくる FactoryBotで作っておいたデータをつ使います。 わからない方は、こちらの記事で確認してください。 [Rails]RSpecでテストを行う準備(FactoryBot使用) spec/system/posts_spec.rb : describe '投稿に関するテスト' do # FactoryBotのテストデータを使う let!(:user) { create(:user) } let!(:post) { create(:post, user_id: user.id) } describe "投稿のテスト" do : beforeを記述 投稿のテストも削除のテストもサインインしてから使う機能なので、サインインしてからテストを実行したいので、beforeでサインインしたあとに各ページに移動しておきます。 spec/system/posts_spec.rb : describe "投稿のテスト" do # userでログインしてから新規投稿画面へ遷移 before do sign_in user visit new_post_path end : describe "削除のテスト" do # userでログインしてから投稿一覧へ遷移 before do sign_in user visit posts_path end : テストの中身を記述 これで、準備ができたので、itの中でテストを実行していきます。 コード内に解説を入れています。 spec/system/posts_spec.rb require 'rails_helper' describe '投稿に関するテスト' do # FactoryBotのテストデータを使う let!(:user) { create(:user) } let!(:post) { create(:post, user_id: user.id) } describe "投稿のテスト" do before do sign_in user visit new_post_path end context "投稿が成功したとき" do it "投稿成功後の遷移先が正しいか" do # contentのフォームにFakerでランダムな5文字の文字列を入れる fill_in 'post[content]', with: Faker::Lorem.characters(number: 5) # 投稿ボタンをクリック click_button "投稿" # 投稿成功後の遷移先が期待したパスになっているか expect(page).to have_current_path posts_path end it "投稿成功後の表示の確認" do # contentのフォームにFakerでランダムな5文字の文字列を入れる fill_in 'post[content]', with: Faker::Lorem.characters(number: 5) # 投稿ボタンをクリック click_button "投稿" # 投稿が成功して"投稿が成功しました"の文字があるか expect(page).to have_content "投稿に成功しました" end end context "投稿が失敗したとき" do it "投稿失敗後の遷移先が正しいか" do # contentのフォームを空にする fill_in 'post[content]', with: nil # 投稿ボタンをクリック click_button "投稿" # エラーが起きて選先が期待したパスになっているか expect(page).to have_current_path posts_path end it "投稿失敗後の表示の確認" do # contentのフォームを空にする fill_in 'post[content]', with: nil # 投稿ボタンをクリック click_button "投稿" # エラーが出てエラーメッセージが表示されているか expect(page).to have_content "入力してください" end end end describe "削除のテスト" do before do sign_in user visit posts_path end it "削除リンクが表示されているか" do # 削除のパスへのリンクがあるか expect(page).to have_link "", href: post_path(post) end it "削除されるか" do # 削除された時データベースから削除されているか expect { post.destroy }.to change(Post, :count).by(-1) end end end マッチャーについてわからない方はこちらの記事参照 [Rails]RSpecでよく使うマッチャー10選 まとめ system specでコントローラーのテストを実施する手順は4つです。 system specファイルの作成 deviseのヘルパーを使えるようにする capybaraの設定 テストコードを書いていく 今回はかんたんな投稿と削除機能のみでしたが、今後も色んなテストコードを投稿していきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

特定の期間の投稿数表示:今日の投稿数、今週の投稿数 scope

やりたいこと 今日の投稿数、昨日の投稿数、前日比% 今週の投稿数、先週の投稿数、先週比を表示させたい。 モデルファイルの記述 book.rb scope :created_today, -> { where(created_at: Time.zone.now.all_day) } scope :created_yesterday, -> { where(created_at: 1.day.ago.all_day) } scope :created_this_week, -> { where(created_at: 6.day.ago.beginning_of_day..Time.zone.now.end_of_day) } scope :created_last_week, -> { where(created_at: 2.week.ago.beginning_of_day..1.week.ago.end_of_day) } モデルファイルにスコープで記述します。こうやってモデルファイルで定義しておけば、 コントローラーもスッキリするのはわかります。 Scopeって何・・・・? モデル側であらかじめ特定の条件式に対して名前をつけて定義し、 その名前でメソッドの様に条件式を呼び出すことが出来る仕組みのこと だそう。 コントローラーの記述 users_controller.rb @books = @user.books.page(params[:page]).reverse_order @today_book = @books.created_today @yesterday_book = @books.created_yesterday @this_week_book = @books.created_this_week @last_week_book = @books.created_last_week bookモデルに記述した定義も、usersコントローラーで使用可能! View <table class="table"> <thead> <tr> <th>今日の投稿</th> <th>昨日の投稿</th> <th>前日比</th> </tr> </thead> <tbody> <tr> <td><%= @today_book.count %></td> <td><%= @yesterday_book.count %></td> <% if @yesterday_book.count == 0 %> <td>前日の投稿はなし</td> <% else %>  <td><% @the_day_before = @today_book.count / @yesterday_book.count.to_f %>  <%= (@the_day_before * 100).round %>%</td> <% end %> </tr> </tbody> </table> <table class="table"> <thead> <tr> <th>今週の投稿</th> <th>先週の投稿</th> <th>比</th> </tr> </thead> <tbody> <tr> <td><%= @this_week_book.count %></td> <td><%= @last_week_book.count %></td> <% if @last_week_book.count == 0 %> <td>先週の投稿はなし</td> <% else %>  <td><% @the_week_before = @this_week_book.count / @last_week_book.count.to_f %>  <%= (@the_week_before * 100).round %>%</td> <% end %> </tr> </tbody> </table> 難しかったのは、前日比、先週比の出し方です。 <td><% @the_week_before = @this_week_book.count / @last_week_book.count.to_f %>  <%= (@the_week_before * 100).round %>%</td> まず、to_fは少数点までの数値まで表示してくれるそうです。 それに100をかけて%で表示されます。 終わりに scope使いこなせるようになりたい!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails, AWS, Dockerでポートフォリオ作成

リンク 【ポートフォリオ】 https://tasty-life.site/ 【Github】 https://github.com/YukiIshizaki0525/TastyLife はじめに 独学でサーバーサイド、フロントエンド、インフラを1から勉強し、Webアプリを作成しました。 本記事で、作成で苦労した点、各種機能、機能実装で参考になったサイトなどを記載いたしますので、現在ポートフォリオ作成中の未経験エンジニアやこれからポートフォリオを作ろうと考えている方のヒントとなれば幸いです。 機能実装方法やテストの書き方などより詳細な内容については別途Qiitaを投稿する予定ですので、更新をお待ちいただければと思います。 本記事についてのご質問や気になった点などがあればできる限り回答いたしますのでTwitterのDMやコメントでお知らせください。 【Twitterアカウント】 https://twitter.com/Luke19770525 概要 一人暮らしの自炊継続のモチベーションアップ及び脱マンネリ化したいという思いから制作 制作背景 私自身一人暮らしで、日々自炊を行っていて、以下のことが課題と感じています。 作る料理がマンネリ化してしまい、モチベーションが下がり、自炊を突然やめてしまう 一人暮らしの自炊についての相談できる機会がない 冷蔵庫に保管している食材を管理できていないため、腐らせてしまったり余っているのに買ってしまう そこで、上記課題を解決できる 一人暮らしの方の自炊を応援するアプリケーション を作成しようと決意しました。 今後の展望 自炊を行う知り合いに使ってもらっていて、ユーザーの貴重な意見を参考に日々改善を行っています。 今後、追加予定の機能及び変更点を5点ほど列挙します。 - アプリケーション自体をVue.jsでSPA化 - APIの導入 - 現在の食材管理状況を毎日18:00にメールで登録済みメールアドレスに配信 - 材料や作り方をドラッグ&ドロップして入れ替えられる仕様 - 作り方の画像プレビュー機能の追加 工夫した点 UI/UX - レシピを見て料理をする際はスマートフォンで見ることも多いのでレスポンシブデザインにしたこと - ページタイトル、文字色、ボーダー等の色を統一したこと - 一覧ページへ移動、削除、送信などをアイコンにして、直感的に操作できるようにしたこと - ホバーアクションやクリックアクションなどCSSアニメーションを取り入れ、動きのあるサイト構成にしたこと - 使いやすい導線設計 機能面 - 一人暮らしでの自炊での悩み(マンネリ化・食材管理など)を解決できるような機能を作成して、一般的なレシピサイトとの差別化を図ったこと - 作りたい料理が決まらない日が多いため、タグ検索機能を追加し、作りたい料理を決められる手助けとなるようにしたこと - 自炊を続けている方の相談や関心が高い相談を見て、自身の生活にも取り入れられるよう、相談のソート機能を追加したこと - 保存中の食材を把握しきれず無駄な買い足しや食材廃棄してしまっていたため、無駄な買い足しや食材廃棄を未然に防ぎ、余り物を有効活用できるよう、保存中の食材管理機能を追加したこと テスト - バリデーションやデザインに不備なく、ユーザーが安心してご利用いただけるようモデルスペック及びシステムスペックを十分に実施 ModelSpec結果 SystemSpec結果 学習で参考になったサイトや教材 ◎は非常に参考になった教材です。(個人の感想です) フロントエンド HTML/CSS/JavaScript ◎【JavaScript&CSS】ガチで学びたい人のためのWEB開発徹底実践(フロントエンド編) 【JS】ガチで学びたい人のためのJavaScriptメカニズム サーバーサイド Ruby ◎プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで Rails ◎Ruby on Rails チュートリアル ◎現場で使える Ruby on Rails 5速習実践ガイド ◎フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座 パーフェクト Ruby on Rails テスト基盤 RSpec ◎Everyday Rails - RSpecによるRailsテスト入門 ◎【Rails】はじめてのRSpec!テストコードを書こう! データベース ◎BigQuery で学ぶ非エンジニアのための SQL データ分析入門 ◎はじめてのSQL ・データ分析入門 -データベースのデータをビジネスパーソンが現場で活用するためのSQL初心者向コース インフラ Docker ◎Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース ◎ゼロからはじめる Dockerによるアプリケーション実行環境構築 【Rails AWS Docker】既存Ruby on Rails + MySQLアプリをDockerで構築し、AWSにデプロイする(1) AWS ◎AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得 ◎サルでもできる!? Rails6 のアプリをAWS EC2にデプロイするまでの全手順【前半】(VPC, RDS, EC2, Capistrano) 苦労した点 フロントエンド レスポンシブデザインのため、scssファイルを多く管理するのが大変でした。 JavaScriptでイベント発火時にエラーは出ないが挙動がおかしい場面が多く修復するのに苦労し、1日悩んでわからないことも多く断念したものもあります。今後はVue.jsをガッツリ勉強して対応できるようにしたい サーバーサイド 【レシピの材料及び作り方の非同期追加及び削除】の機能実装は苦労しました。Cocoon(Gem)を入れて当初実装していましたが、デザインが当たらなかったりなど、ブラックボックスに感じたので模索しながらGemを使わずに実装しました。こちらのサイトが唯一あって助かりました。 create a nested form in rails from scratch devise及びgmail認証 deviseもブラックボックスでカスタマイズするのに苦労しました。特にメール認証ではgmailにメールが届かないことが多く挫折しかけました。メール文章もデフォルトのものがあたってしまい、メール文章をカスタマイズするのにも一苦労しました。Qiitaの記事などを参考になんとか自身がイメージする形に仕上がったので良かったです。その関連でActionMailerについての知見も増え、gmailを使った退会処理機能などを実装することができました。 インフラ AWSとDockerの連携 ポートフォリオ作成初期にAWSとDockerを構築してから自動デプロイできるように努力しましたが、当初は敷居が高いと感じ、挫折しました。付け焼き刃では通用しないと思い、サイトや書籍を参考にチャレンジしたら、スムーズに構築することができました。何事も基礎がないとダメってことですね。 使用画面 トップページ ログインページ レシピ一覧(材料・レシピ名での検査、タグでのソートが可能です) レシピ詳細とコメント 相談一覧(回答数・気になる数などでソートが可能です) 相談詳細とコメント ユーザー詳細 食材管理ページ(自身のものしか見れません) 使用技術 フロントエンド HTML/CSS/Sass JavaScript(ES6) バックエンド Ruby 2.6.5 Rails 6.0.3 テスト基盤 RSpec 3.9 FactoryBot 4.10.0 データベース MySQL 5.7 インフラ Docker 20.10.7 Docker Compose 1.29.2 AWS(VPC, EC2, IAM, RDS, InternetGataway, SecurityGroup, Subnet, Route53, ALB, ACM, S3, CloudFront) Nginx 1.15.8 AWS構成図 ER図 機能一覧 基本機能 ユーザー新規登録(Gmail認証) ログイン・ゲストユーザーログイン ログアウト ログインセッション保持 ログインパスワード再設定(Gmail認証) アカウント認証メール再送 アカウントの凍結解除メール送信 ユーザー退会(論理削除) 退会済みユーザーアカウント復旧機能(Gmail認証) ユーザーアカウント情報変更(メールアドレス・プロフィール画像・ユーザー名・パスワード) メールアドレス変更(Gmail認証) フォロー中ユーザー一覧及びフォロワー一覧閲覧 ユーザーフォロー ユーザー詳細及びマイページ表示(レシピ・いいねしたレシピ・相談・気になっている相談・食材管理) ユーザー一覧 レシピに関する機能 ログイン済み レシピ投稿 材料及び作り方の非同期追加及び削除 レシピの画像添付(画像プレビュー可能) 作り方に画像添付 関連タグ付け(既定6つのタグ複数選択可能) レシピ一覧 レシピ詳細 レシピ編集(投稿したユーザーのみ) レシピ削除(投稿したユーザーのみ) コメント閲覧 コメント投稿 コメントに対する返信 コメント削除(投稿したユーザーのみ) レシピにいいねをつける レシピいいね数確認 ワードで検索(レシピ名及び材料名) 関連タグで検索 タイムライン(自身及びフォローしている方の投稿のみ表示) 未ログイン レシピ一覧 レシピ詳細 コメント閲覧 ワードで検索(レシピ名及び材料名) 関連タグで検索 相談に関する機能 ログイン済み 相談投稿 相談一覧 相談詳細 相談編集(投稿したユーザーのみ) 相談削除(投稿したユーザーのみ) 相談ソート(投稿が新しい順・投稿が古い順・気になるが多い順・回答数が多い順) コメント閲覧 コメント投稿 コメントに対する返信 コメント削除(投稿したユーザーのみ) 相談に気になる追加 相談気になる数確認 未ログイン 相談一覧 相談詳細 コメント閲覧 相談ソート 食材管理に関する機能 ログイン済みかつ自身のみ 保管中の食材追加・登録・編集・削除 食材画像,数量,個数,賞味期限,メモの登録 賞味期限までの日数確認 最後に ポートフォリオ作成は転職活動のために作成するのではなく、自身やユーザーの課題解決のために、ポートフォリオ制作を行うことに注力したので、非常に達成感があります。 ポートフォリオを使っていただいた方からありがたいことに改善点をいただいているので、作成途中よりも作成後の方がIssueが多いです(笑) ですが、実際にユーザーの生の声を聞いて、ユーザーのことをより考えながら改善や機能実装をしようと開発を進めているため、以前よりも幸せに感じながら実装ができています。 転職後も新しい技術に触れることが多いと思うので、インプットした後に本ポートフォリオに取り入れて、アウトプットの場にも使いたいと思います。 ここまでご覧いただきましたありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【500エラー】【AWS】RDSに日本語が保存できない問題 Rails on Docker

docker環境でrails6アプリを構築し、苦労してようやくEC2上にアプリをデプロイできたと思ったら、 何故かdeviseのユーザー登録時メール認証機能(comfirmable)、お問い合わせメール機能、ゲストログイン機能が500エラー。。。 メールに関する部分だけがエラーになっているからてっきりSMTPサーバーが機能していないのかな?などと推測し、 SESの設定を見直すも・・・・ 解決できず。。 原因:RDSで作成したMySQLのDBに日本語が保存できないこと RDSではDefaultでcharacter-setにlatin1が割り当てられるため、日本語を利用する際はutf8などに変更してあげる必要があったのでした。 そのためRDSで設定したMySQLに関するエラーが発生していました。 それに気づかずてっきりSMTPサーバー関係のエラーだと決めつけて数日もがいてました。。 そもそも私はログイン済みユーザーじゃないと新規投稿機能だったりフォローだったり、全ての機能を利用できないように制限をかけていたので 他のページの確認ができていなかったのですが、 本当はメールに関する部分だけがエラーになっていたのではなくて、 全体がエラーになっていたんだと思います。。。 解決につながったこと:エラーログの確認 エラーがどこで発生しているのか、原因の切り分けも大事ですが、エラーログを確認することが何より最も重要だと気づかされました。 docker環境でつくったアプリをEC2にデプロイしたら、本番環境のみエラーになってしまう。 開発環境ではエラーないのに。 その場合はどこでエラーログを見られるの?? そもそもエラーログ出す方法なんてないんじゃないか?? などと一週間くらいパニック状態でしたが(笑) ログの出し方が分かったことで2、3時間くらいで解決できてしまいました!!! エラーログの出し方 [ec2]$ cd /var/www/アプリ名 [ec2]$ docker-compose exec app bash root@f4658ed2b15e:/var/www/アプリ名# cd /var/www/アプリ名 root@f4658ed2b15e:/var/www/アプリ名# ls root@f4658ed2b15e:/var/www/アプリ名# cd log root@f4658ed2b15e:/var/www/アプリ名/log# ls root@f4658ed2b15e:/var/www/アプリ名/log# tail -f production.log tail -fを使うことで、ページにアクセスしたときのエラーをリアルタイムで見ることができて便利です。 解決策:RDSの設定変更 下記記事の通りに設定したら解決しました。ありがとうございます!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

開発学習備忘録

開発に関する備忘録 Gitコマンド git add -A git commit -m "コメント" Git-flowに関する参考サイト https://qiita.com/KosukeSone/items/514dd24828b485c69a05 Vimコマンド 参考サイト https://qiita.com/hide/items/5bfe5b322872c61a6896 Railsコマンド Dockerコマンド docker-compose stop docker-compose up -d その他 ローカルホストの接続先 http://localhost:3000/ figma参考サイト https://qiita.com/Hrioaki/items/d428d8318780a47f87ff VSCodeショートカット参考サイト https://qiita.com/naru0504/items/99495c4482cd158ddca8
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails バリデーションの使い方と種類について

1 バリデーションとは データを保存する,不正なデータがデータベースに保存されないようにデータをチェックするシステムです。 2 なぜバリデーションを使うのか. 正しいデータだけをデータベースに保存するために使われます。 3 使い方 validates :カラム名(シンボル指定),検証ルール(シンボル指定) 4 validationの種類 ・presence: true カラムの値が存在するかチェック class Post < ApplicationRecord validates :content, {presence: true} end ・inclusion: { in: [true, false] } boolean属性が空でないこと class User < ApplicationRecord validates :birthplace, inclusion: { in: [true, false] } end ・{acceptance: true} チェックボックス class User < ApplicationRecord validates :actor, {acceptance: true} end ・文字数の指定  lengthを使って{maximum:数値}を指定して最大文字数を{minimum:数値}を指定して最小文字列を指定 inを使い範囲や文字数飲みのバリデーションをかける。isで指定した数字飲み class Post < ApplicationRecord validates :content, {length: {maximum:100} } #最大100文字以下 validates :content, {length: {minimun:30} } #30文字以上 validates :content, {length: {in: 10..80} } #10文字以上80文字以下 validates :content, {length: {is: 30 }} #30文字のみ end  
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

private と protected [Ruby on Rails]

"private"と"protected" について 使用例 applicationcontrolle.rb def update @user.update(user_params) redirect_to users_path(@user) end private def user_params params.require(:user).permit(:name, :introduction, :profile_image) end userscontroller.rb protected def after_sign_in_path_for(resource) user_path(current_user) end 説明  いずれも、データベースにあるデータを書き換えるときに必要な記述になります。 Rubyは安全性を考慮し、外部からデータを変えられないようになっています。いずれかの記述をすることで、データの変更が可能になります。 「private」と「protected」の違い ・「private」は、自分だけが変更できる。 ・「protected」は、自分と仲間(同じクラスのインスタンスに加え子孫クラスのインスタンス)が変更できる。 データを守る強度が、「private > protected」になります。 基本はprivateを使っておけば問題ありません。 今回出てきた単語について ・???_params ・after_sign_in_path_for(resource)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む