20211007のRailsに関する記事は18件です。

バリデーションとは!

①結論! バリデーションとは、データの入力に制約をかけるという事です! データを登録する際に、一定の制約をかけることを言います! 例えば、以下のようなものがあります! ・空のデータが登録できないようにする!(ブログ記事など) ・既に登録されている文字列を登録できないようにする!(メールアドレスの登録など) ・文字数制限をかける!(パスワードなど) バリデーションを設ける際は、モデルにvalidatesメソッドを記述します! ②.validatesメソッド validatesとは、バリデーションを設定する時に使用するメソッドです! 以下が記述方法になります! モデルファイルへ記述 validates :カラム名, バリデーションの種類 これが書き方です! 続いて下記の例は、presence: trueと記述することで、nameカラムが「空ではないか」というバリデーションを設けています! モデルファイルへ記述 validates :name, presence: true これで完成です! このバリデーションを設けることで、名前が空欄の時データベースに保存できなくなります! つまり、値を必ず入れなければいけません! もし、空欄で登録しようとすると、エラーが発生します! 他にも種類がたくさんあるので、徐々にアウトプットして行こうと思います! ③.まとめ よく使用するので、覚えておくべきですね! バリデーションだけでも、かなりの種類があるみたいですね汗 確実に理解していかないとです! 何か説明で間違っていたらご指導お願い致します(_ _)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのオリジナルアプリ公開までの道のり

公開までの道のり 月 やってたこと 5月 tech camp(教養コース入学) 7月 tech camp(転職コース入学、夜間休日タイプ) 8月 カリキュラム終了 9月 オリアプ作成開始 10月 オリアプ完成 卒業予定は1月、笑 公開したアプリの概 アプリ名 FX-Traders https://fxtraders.jp どんなアプリ? fx取引の記録を公開できるアプリになります。そしてその記録をもとにグラフを作り結果を解析できるアプリです。 それを公開することで 自身が決めた取引ルールの厳守 取引ルールのブラッシュアップ 第三者からのフィードバック 他者取引への理解 などを狙っています。 なんで作ったの? まずは自分で欲しかったから。一番大きな理由でもありますね。学生の頃にfxの記録を紙のノートに書いていて、画像を残せないのが残念で書くだけで満足していて、笑笑 こんなことを思っている人がたくさんいるんじゃないか?って思ったのも作った理由のひとつです。 あとはコロナ禍で投資を始める人も増えていることが想定されますから需要もあるかと思ってもいます。 なので、 自分が使いたい あるといいなと思っている人もいるのでは? コロナ禍で投資人口も増えているのでは? と言うところでこのアプリを作りました! アプリ実装項目 取引記録 投稿 編集 削除 検索(gem, ransack) 画像投稿(gem, active storage) いいね機能(ajax, font awesome) 取引手法 投稿 編集 削除 検索(rgem, ansack) 画像投稿(gem, active storage) いいね機能(ajax, font awesome) コメント 投稿(ajax) 削除(ajax) ユーザー関連 フォロー機能 グラフ表示(gem, chartkick) メール認証機能 管理者機能 seo対策 メタtag(gem, meta_tags) ぱんクズリスト(gem, gretel) サイトマップ(gem, sitemap_generator) サイトマップの自動更新(gem, whenever) デプロイ aws(ec2, s3, route53) mysql(maria DB) Unicorn Nginx 自動デプロイ(gem, Capistrano) ssl証明(AWS, ACM) その他 ページネーション 日本語対応(gem, rails-i18n) 広告のランダム表示 問い合わせ(ライン公式, font awesome) ハンバーガーメニュー PV数(閲覧数)取得(gem, impressionist) OGPの設定(gem, meta-tags) アプリを作った感想 勉強期間は約3ヶ月ですが自分的には満足できるものができました。が、まだ実装したいことがたくさんあるので追加実装を続けていく予定です。 さらにreact, react nativeを勉強していきたいなと思っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【超初心者向け】belongs_toとhas_many、アソシエーションってなに?

belongs_toとhas_many アソシエーションについて belongs_toとhas_manyが「あれ?どっちがどっちだっけ?」となっていたので、備忘録として記載。 そもそも関連付け(アソシエーション)とは? テーブル同士に関係があることを表現すること。 例えば、茶川さんという著者(author) がいて、羅生マンという本(book)を書いていたとする。(※架空の著者・本です。) 茶川さんはauthorテーブル、羅生マンはbook テーブルにそれぞれ保存されます。この状態は、一人の作者に対して一冊の本なので、「1対1」です。 ここで、茶川さんが「蜘蛛と糸」という本(book)を書いたとする。 すると、bookテーブルには新たに「蜘蛛と糸」という本が追加されるので、 一人の著者に対して複数の本が関連付いていることになります。 これが「1対多」の関係になるということになります。この際に、model 記載するのが「belongs_to」と「has_many」ということになります。 今回の例でいうと、一人の著者が複数の本を書いている(ここでは都合よく本が著者に従属していると考える)ため、 belongs_to・・・book has_many・・・author ということになります。 つまり、それぞれのmodel 記載する場合は、このように記載しましょう。 class Autor < ApplicationRecord has_many :books #bookモデルだが、1対多の「多」に該当するため、ここではbooksになる。has_oneを用いる場合は「book」 end class Book < ApplocationRecord belongs_to :autor end 以上簡単ではありますが、自分が忘れがちなポイントに関して書き留めておきました。 自分と同じ初学者の方のとっかかりとして使用していただければ幸いです。また、個人的にはQiitaだけではなくしっかりと公式のドキュメントを読んでいく癖もつけていきたいです!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

railsチュートリアル第七章 エラーメッセージ

エラーメッセージ ユーザー登録の失敗によるエラーメッセージを表示させよう。 Userコンソールを使い、誤ったユーザー情報を入力してみよう。 >> user = User.new(name: "Foo Bar", email: "foo@invalid", ?> password: "dude", password_confirmation: "dude") (1.6ms) SELECT sqlite_version(*) => #<User id: nil, name: "Foo Bar", email: "foo@invalid", created_at: nil, updated_at: nil, password_digest: [FILTERED]> >> user.save (0.1ms) begin transaction User Exists? (0.8ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "foo@invalid"], ["LIMIT", 1]] (0.1ms) rollback transaction => false >> user.errors.full_messages => ["Email is invalid", "Password is too short (minimum is 6 characters)"] すぐにエラーメッセージが表示された。 パスワードが短すぎるらしい。 エラーメッセージを入力させるためにHTMLを作成する ユーザー登録失敗時にエラーメッセージが表示されるようにする app/views/users/new.html.erb <% provide(:title, 'Sign up') %> <h1>Sign up</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_with(model: @user, local: true) do |f| %> <%= render 'shared/error_messages' %> <%= f.label :name %> <%= f.text_field :name, class: 'form-control' %> <!--名前をつける欄を作成--> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <!--email--> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <!--パスワード--> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <!--多分 確認用パスワード--> <%= f.submit "Create my account", class: "btn btn-primary" %> <% end %> </div> </div> 'shared/error_messages'はまだ作っていない。 のでこれから作成する。 mkdir app/views/shared 新しくファイルを作成 ubuntu:~/environment/sample_app (sign-up) $ c9 open _error_messsages.html.erb フォーム送信時にエラーメッセージを表示するためのパーシャル app/views/shared/_error_messages.html.erb <% if @user.errors.any? %> <div id="error_explanation"> <div class="alert alert-danger"> The form contains <%= pluralize(@user.errors.count, "error") %>. <!--@user.errors.countはエラーの回数--> <!--pluralizeは引数が出力される--> <!--エラーの回数と"error"の文字列が表示される--> </div> <ul> <% @user.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> 第一引数に基づいて第二引数が複数形になる。 引数が出力されるらしい。 >> helper.pluralize(1, "error") => "1 error" >> helper.pluralize(5, "error") => "5 errors" エラーメッセージにスタイルを与えるためのCSS app/assets/stylesheets/custom.scss /* forms */ . . . #error_explanation { // エラーメッセージにスタイルを与えるため color: red; ul { color: red; margin: 0 0 30px 0; } } .field_with_errors { // field_with_errorsを持ったdivタグでエラー箇所を自動的に囲んでくれます。 @extend .has-error // @extend関数を使ってBootstrapのhas-errorというCSSクラスを適用 .form-control { color: $state-danger-text; } エラーの数だけメッセージを表示する。 第一引数に基づいて第二引数が複数形になる。 無効なユーザー登録情報を送信したときのエラーメッセージが分かりやすくなります ユーザー登録フォームで空のパスワードを入力すると2つの同じエラーメッセージが表示されてしまいます。 まだ工夫が必要なようだ。 演習 1.最小文字数を5に変更すると、エラーメッセージも自動的に更新されることを確かめてみましょう。 user.rb class User < ApplicationRecord before_save { email.downcase! } # データベースに保存する前に処理をする。 # 入力されたメールアドレスを小文字にする。 validates :name, presence: true, length: { maximum: 50 } #属性はname,属性の存在を検証、 最大50字まで VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, #最大255字まで format: { with: VALID_EMAIL_REGEX }, uniqueness: true #??? has_secure_password #セキュアなパスワードの実装 validates :password, presence: true, length: { minimum: 5 } # パスワードのバリデーションの設定 # 最低は六文字 end test "password should have a minimum length" do @user.password = @user.password_confirmation = "a" * 4 # 文字が五文字 assert_not @user.valid? # このパスワードも認められないよね? end end プレビューを確認 Password is too short (minimum is 5 characters)を表示された。 2.未送信のユーザー登録フォーム(図 7.13)のURLと、送信済みのユーザー登録フォーム(図 7.19)のURLを比べてみましょう。なぜURLは違っているのでしょうか? 考えてみてください。 未送信登録フォーム https:#####.com/signup 送信済み登録フォーム https:######.com/users signupとusersの違いがある。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

railsチュートリアル第七章 Strong Parameters

Strong Parameters user = User.new(params[:user]) paramsハッシュ全体を初期化するという行為はセキュリティ上、極めて危険 この場合誰でも管理者に化けることができるため paramsを使うのに条件をつけた。 paramsハッシュでは:user属性を必須とし、名前、メールアドレス、パスワード、パスワードの確認の属性をそれぞれ許可し、 それ以外を許可しないようにする。 params.require(:user).permit(:name, :email, :password, :password_confirmation) :user属性でなければ、情報を確認できないようにした。 それを解決した。 class UsersController < ApplicationController . . . def create @user = User.new(user_params) # 外部メソッドを使う if @user.save # 保存の成功をここで扱う。 else render 'new' # 保存に成功しなければnewアクションに移動する end end private #外部から使えないようにする #習慣的に二つインデントを下げる def user_params # Usersコントローラの内部でのみ実行される # Web経由で外部ユーザーにさらされない params.require(:user).permit(:name, :email, :password, :password_confirmation) end end 間違ってもエラーメッセージが出てこない かつ有効なユーザー情報を入力しても登録されない。 これから改良するらしい。 演習 1./signup?admin=1 にアクセスし、paramsの中にadmin属性が含まれていることをデバッグ情報から確認してみましょう。 --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess admin: '1' controller: users action: new permitted: false adminが入っていた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

railsチュートリアル第七章 ユーザー登録失敗

ユーザー登録失敗 フォームを理解するにはユーザー登録の失敗のときが最も参考になる。 この節では、無効なデータ送信を受け付けるユーザー登録フォームを作成し、ユーザー登録フォームを更新してエラーの一覧を表示します。 正しいフォーム Rails.application.routes.draw do root 'static_pages#home' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact' get '/signup', to: 'users#new' resources :users end urlにusersを入れることができる。 それによりcreateアクションを使い、新規作成者を作ることができたりした。 <form action="/users" class="new_user" id="new_user" method="post"> POSTリクエストを/usersというURLに送信 ユーザー登録の失敗に対応できるcreateアクション class UsersController < ApplicationController . . . def new @user = User.new #新しくユーザーオプジェクトを作成する # オブジェクトの属性をつける end def create @user = User.new(params[:user]) # 実装は終わっていないことに注意! if @user.save # 保存の成功をここで扱う。 else render 'new' # 保存に成功しなければnewアクションに移動する end end end プレビューで確認 失敗 ActiveModel::ForbiddenAttributesError in UsersController#create createアクションで失敗したらしい。 Request Parameters: {"authenticity_token"=>"dfo0Ltyd8b+HqfZYMQ4dsyiL4b1FM0LqBY3mAQfni3QmVBfVE7B9kwrZIQ3kuT/QLU/He+TpHuJQrkuWwFvUNw==", "user"=>{"name"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create my account"} Usersコントローラにparamsとして渡されます <input id="user_email" name="user[email]" type="email" /> "user[email]"という値は、userハッシュの:emailキーの値と一致 2つのコードの意味は一緒らしい。 @user = User.new(params[:user]) @user = User.new(name: "Foo Bar", email: "foo@invalid", password: "foo", password_confirmation: "bar") 昔のバージョンのRailsでは、次のコードでも動いた。 @user = User.new(params[:user]) しかし悪意からの対策としてわざとエラーを起こすStrong Parametersという技術で今は動かない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

`rails s` 実行時にRubyGemsのエラーが発生する

環境情報 macOS Big Sur 11.6 Ruby 2.6.1 Rails 5.2.6 起きたこと OSのアップデートやrbenvの再インストールを行った後、 rails s や rails c を実行した時に下記エラーが発生するようになってしまった   (起きていた現象として、エラーが発生するだけで起動は行われる) /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/rubygems_integration.rb:12: warning: already initialized constant Bundler::RubygemsIntegration::EXT_LOCK /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/rubygems_integration.rb:12: warning: previous definition of EXT_LOCK was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/version.rb:4: warning: already initialized constant Bundler::VERSION /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/version.rb:10: warning: previous definition of VERSION was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:4: warning: already initialized constant Bundler::WINDOWS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:4: warning: previous definition of WINDOWS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:5: warning: already initialized constant Bundler::FREEBSD /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:5: warning: previous definition of FREEBSD was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:6: warning: already initialized constant Bundler::NULL /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:6: warning: previous definition of NULL was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:12: warning: already initialized constant Bundler::CurrentRuby::KNOWN_MINOR_VERSIONS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:12: warning: previous definition of KNOWN_MINOR_VERSIONS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:26: warning: already initialized constant Bundler::CurrentRuby::KNOWN_MAJOR_VERSIONS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:24: warning: previous definition of KNOWN_MAJOR_VERSIONS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:28: warning: already initialized constant Bundler::CurrentRuby::KNOWN_PLATFORMS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:26: warning: previous definition of KNOWN_PLATFORMS was here 解決方法 gem update --system を実行する(gemコマンドをアップデートする) 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails-i18n による日本語化

基本的な流れ(自分用に) gem 'rails-i18n'をインストールする Gemfile gem 'rails-i18n' Gemfileに「rails-i18n」を導入する。 ターミナル bundle install 「rails-i18n」をインストール デフォルトの言語を日本語に設定する、i18nの複数のlocalesファイルが読み込まれるようにする config/application.rb module RunteqNormal class Application < Rails::Application config.load_defaults 5.2 config.generators.system_tests = nil config.generators do |g| g.skip_routes true g.assets false g.helper false g.test_framework false end #ここから追記 #↓でデフォルトの言語を日本語に設定する。 config.i18n.default_locale = :ja #↓でi18nの複数のlocalesファイルが読み込まれるようになる config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] #ここまで end end views/model用のlocalesファイルをconfig/locales下に作成する 画面表(HTML)を担当するViewとDB関連の処理を担当するModelでは、ファイルを分けておく必要がある。 今回は、View用の「config/locales/view/ja.yml」とModel用の「config/locales/activerecorder/ja.yml」を作成。 それぞれのja.ymlファイルに日本語の設定をする config/locales/views/ja.yml ja: defaults: login: 'ログイン' register: '登録' logout: 'ログアウト' users: # controller/usersに対応 new: # newアクションに対応 title: 'ユーザー登録' to_login_page: 'ログインページへ' user_sessions: new: title: 'ログイン' to_register_page: '登録ページへ' password_forget: 'パスワードをお忘れの方はこちら' boards: index: title: '掲示板一覧' new: title: '掲示板作成' bookmarks: title: 'ブックマーク一覧' profiles: show: title: 'プロフィール' config/locales/activerecorder/ja.yml # モデルは全て activerecord 下に記述することで、「User.model_name.human」、「User.human_attribute_name({attr_name})」で使用可能になる。 ja: activerecord: models: user: 'ユーザー' board: '掲示板' attributes: user: email: 'メールアドレス' password: 'パスワード' password_confirmation: 'パスワード確認' last_name: '姓' first_name: '名' 基本的な使い方 Viewの場合 app/views/users/new.html.erb <%= t 'users.new.title' %> →「config/locales/views/ja.yml」に、「users: new: title: ’ユーザー登録’」と記述してあるので「ユーザー登録」と表示される ・対応するビューの中ではツリーを省略できるので、「users.new」の部分は省略して書くことができる。 app/views/users/inew.html.erb #ja.ymlファイルの # users: # new: #   の部分を自動で読み込んでいる状態 <%= t ‘.title’ %> →同じく「ユーザー登録と表示される」 ・「users/index.html.erb」に記述されているので、「ja.yml」ファイルの「users: new:」の部分を自動的に読み込んでいる。 Modelの場合 app/views/users/inew.html.erb <%= t('activerecord.models.user') %> →「onfig/locales/activerecorder/ja.yml」に「activerecord: models: user: ‘ユーザー’」と記述してあるので「ユーザー」と表示される app/views/users/inew.html.erb <%= t('activerecord.attributes.user.email') %> →「メールアドレス」と表示される 「User.model_name.human」、「User.human_attribute_name({attr_name})」を使う app/views/users/inew.html.erb #<%= t('activerecord.models.user') %> を書き換える <li><%= User.model_name.human %></li> →「ユーザー」と表示される app/views/users/inew.html.erb #<%= t('activerecord.attributes.user.email') %> を書き換える <li><%= User.human_attribute_name(:email) %></li> →「メールアドレス」と表示される 実際の記述例 app/views/users/inew.html.erb <%= form_with model: @user, local: true do |f| %> <div class="form-group"> <%= f.label :email, User.human_attribute_name(:email) %> <%= f.text_field :email, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password, User.human_attribute_name(:password) %> <%= f.password_field :password, class: 'form-control' %> </div> 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

enumの値によってviewページの表示を変えたい

はじめに 現在プログラミング学習を始めて3ヶ月目の初学者です。 学んだことをqiitaに投稿という形でアウトプットするため、また備忘録として記事を作成しました。 enumの値によってviewページの表示を変えたい 今回Todoアプリを作るに当たってタスクの種類をenumで管理してるので、そのenumの値によってそれぞれのタスクの種類のviewだけに表示させたい 考えた方法 ・controllerで指定 controllerで指定 @tasks = Task.categories.find(2) で行けるかなと思ったが undefined method `sentence' for ["よく使うタスク", 0]:Array と出るので確かにsentenceカラムはこれだと表示できないよなぁ。 @tasks = Task.where(category:2) 今度こそと思ったがviewにはなにも表示されない と思ったがcreate時のログを見たところ "category"が"categories"になっていたのでform_withの記述をf.select :categoryに直してcreateしたら表示されました! 最後に qiitaへの投稿に慣れていないので、分かりづらい上に情報が少ないですが、これから欠かさず投稿していこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsプロジェクト内でReactを使う方法

RailsとReactを分離させてSPAで動かす記事はたくさん見つかるけど、そうではなくRailsプロジェクトの一部でReactを使う方法。 react-railsというgemを使う方法です。ほぼ以下のgemでの導入方法に近い記事です。 reactjs/react-rails: Integrate React.js with Rails views and controllers, the asset pipeline, or webpacker. 環境 Rails 6.1.4 Ruby 3.0.0 Reactの導入 まず導入したいrailsプロジェクトディレクトリ内に移動し、railsコマンドでReactとその関連ファイルをインストール。 % rails webpacker:install:react インストールすると、app/javascript/packs/hello_react.jsxが作成される。これを任意のviewファイルに挿入する。 中身は以下。 // Run this example by adding <%= javascript_pack_tag 'hello_react' %> to the head of your layout file, // like app/views/layouts/application.html.erb. All it does is render <div>Hello React</div> at the bottom // of the page. import React from 'react' import ReactDOM from 'react-dom' import PropTypes from 'prop-types' const Hello = props => ( <div>Hello {props.name}!</div> ) Hello.defaultProps = { name: 'David' } Hello.propTypes = { name: PropTypes.string } document.addEventListener('DOMContentLoaded', () => { ReactDOM.render( <Hello name="React" />, document.body.appendChild(document.createElement('div')), ) }) ファイル先頭にも書いてある通り、<%= javascript_pack_tag 'hello_react' %>をrailsのviewファイルに挿入すればこのコンポーネントがレンダリングされる。 ReactコンポーネントをRailsのviewで表示する 実際にやってみる。 ※以下は挿入したいviewファイルが既にあればとくにやらなくて大丈夫です。 viewを作成するためBookモデルのscaffoldを実行しマイグレート。 % rails g scaffold Book title:string content:text % rails db:migrate rails sで先に画面を確認。 http://localhost:3000/books ここに先ほどのhello_react.jsxを挿入してみる。 app/views/books/index.html.erb <% # 以下に挿入 %> <%= javascript_pack_tag 'hello_react' %> <p id="notice"><%= notice %></p> <h1>Books</h1> <table> <thead> <tr> <th>Title</th> <th>Content</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @books.each do |book| %> <tr> <td><%= book.title %></td> <td><%= book.content %></td> <td><%= link_to 'Show', book %></td> <td><%= link_to 'Edit', edit_book_path(book) %></td> <td><%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New Book', new_book_path %> 表示を確認すると、確かにHello React!がレンダリングされている。 ただこの状態だと挿入した行の位置に関わらずReactコンポーネントが最後にレンダリングされてしまうのでそれを解消する。 react-railsの導入 Gemfileに以下を追記。 gem 'react-rails' 追記したgemをインストール。 % bundle install 次に以下のコマンドを実行。 % rails g react:install するとapp/javascript/componentsというフォルダが作られるので、ここにhello_react.jsxをここに移動。 レンダリングに関しては react-railsがやってくれるので、移動した後以下のように変更。 app/javascript/components/hello_react.jsx // Run this example by adding <%= javascript_pack_tag 'hello_react' %> to the head of your layout file, // like app/views/layouts/application.html.erb. All it does is render <div>Hello React</div> at the bottom // of the page. import React from 'react' import ReactDOM from 'react-dom' import PropTypes from 'prop-types' const Hello = props => ( <div>Hello {props.name}!</div> ) Hello.defaultProps = { name: 'David' } Hello.propTypes = { name: PropTypes.string } // 以下を削除 // document.addEventListener('DOMContentLoaded', () => { // ReactDOM.render( // <Hello name="React" />, // document.body.appendChild(document.createElement('div')), // ) // }) // 以下を追記 export default Hello react-railsを導入したことによって、react_componentというメソッドが使えるようになる。レンダリングしたいReactコンポーネントの読み込みも以下のように記述を変更。 # 以下を削除 <%= javascript_pack_tag 'hello_react' %> # 以下を追記 <%= react_component('hello_react') %> <p id="notice"><%= notice %></p> <h1>Books</h1> <table> <thead> <tr> <th>Title</th> <th>Content</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @books.each do |book| %> <tr> <td><%= book.title %></td> <td><%= book.content %></td> <td><%= link_to 'Show', book %></td> <td><%= link_to 'Edit', edit_book_path(book) %></td> <td><%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to 'New Book', new_book_path %> これで再度レンダリングしてみる。 これで任意の場所にReactコンポーネントを差し込むことができた! viewファイルから値を渡したい場合は、以下のようにする。 <%= react_component('hello_react', { name: "react-rails" }) %> これ以降追加したいReactコンポーネントがあれば、app/javascript/components配下にjsxなりtsxのファイルを作ればいい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]deviseで使えるモジュールについて

初めに なぜこの記事を書きたかったのか deviseを使うときのmodelの記述でわからないままにしてあったのがあったので、勉強するため記事にしたかった 環境 ・Macbook Air (Retina, 13-inch,2019) ・プロセッサ 1.6GHz デュアルコアIntel Core i5 ・メモリ 8GB 2133 Mhz LPDDR3 ・MacOS Big Sur バージョン 11.5.2 記事の目次 1)deviseって?モジュールって? 2)前提条件(deviseの導入) 3)モジュールの種類 4)モジュールの追加方法 5)最後に deviseって?モジュールって? deviseについて deviseとはgemの一種で導入することでログイン/新規登録機能が簡単に使えるようになれる! モジュールについて モジュールのイメージは機能が入っている箱の名前だと思う!これを使うことで1からコードを組んで作成しなくとも自分がほしいシステムと近いものが使えるのです! 前提条件(deviseの導入) (製作中:ここにリンクをはろうと思う) モジュールの種類(10種類) デフォルトで入っているもの 上記の画像のdevise後の青い文字はdeviseを導入するときにdefaultで入っている機能です。 (モジュール名:database_authenticatable) =メールアドレスとパスワード入力のログイン機能 (モジュール名:registerable) =サインアップ機能 (モジュール名:recoverable) =パスワードリセット機能 (モジュール名:rememberable) =プラウザを閉じてもログインしてくれる機能 (モジュール名:validatable) メールアドレスとパスワードのバリデーション機能 追加で入れれるもの 上記の画像のコメントアウトされている緑色の単語はdefault時にはないものです。 (モジュール名:confirmable) =サインアップしたときに登録したメールを使って、userにメールアドレスを確認させることができる機能 (モジュール名:lockable) =設定した回数分ログインが失敗されたときにアカウントをロックさせる機能 (モジュール名:timeoutable) =一定期間アクセスがないと強制ログアウトさせる機能 (モジュール名:trackable) =ログイン時の情報をデータベースに保存することができる機能 (モジュール名:omniauthable) =Twitterやgoogleアカウントなどでログインが可能になる機能 モジュールの追加方法 1)rails g devise:installコマンドで生成したマイグレーションファイルを開く 2)使いたいモジュールのコメントをコメントアウトする。(例としてTrackableをコメントアウトしてみる) 3)ターミナルでrails db:migrateをする 結果)追加されるもの (routes) devise_for :users (model) devise : Trackableが追加される ※これで、サーバーを再起動してユーザがログインすると、trackableで追加したカラムに情報が保存される。 最後に modelに書いてあったdevise :ooooを覚えなくともログイン/新規登録機能が使えてたのでスルーしていましたが、deviseで使える機能がまだあることがしれて開発の幅が広がったので言語化してよかったと思った!実際に他のモジュールも使い始めたらまた記事に書こうと思いますb ココまで読んでくださいましてありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

デプロイに使用したAWSのサービスとインフラ知識のまとめ

ポートフォリオのデプロイに使用したAWSのサービスとその周辺のインフラ知識についてまとめました。 サービス一覧、 VPC RDS EC2 Route53 IAM S3 ACM ALB VPC VPCとは? Virtual Private Cloudの略で、AWS上に仮想ネットワークを作成できるサービス。 AWSの広いネットワークの土地の中で自分だけの空間を作成できる。 リージョン AWSの各サービスが提供されている地域のこと。 AWSのサービスを使う場合まずリージョンを設定し、リージョン毎にサーバーを作っていく。 アベイラビリティゾーン 独立したデータセンターのこと。 どのリージョンにも複数存在している。理由は災害が起きて1つのアベイラビリティゾーンが止まっても他のアベイラビリティゾーンを使えるから。 サブネット ネットワークを分割して作った小さなネットワークのこと。 サブネット内で1つをインターネットからアクセス可能なWebサーバー、もう1つをアクセスできないDBサーバーのように複数分けて作ることができる。 複数のアベイラビリティゾーンの中にそれぞれサブネットを作ることで冗長性を高める。 IPアドレス ネットワーク構築の際には、まずIPアドレスの範囲を決める必要がある。 IPアドレスとは、インターネットの住所で重複なしの32ビットの整数で8ビット4つの組に分け10進数で表現されている。 IPアドレスの種類は、インターネットに接続する際に使用するパブリックIPアドレスと、インターネットの接続には使用しないプライベートIPアドレスがある。 IPアドレスはネットワーク部とホスト部に区分けすることで範囲を表記してる。 CIDR表記 IPアドレスの後ろに「/」を書きその後ろにネットワーク部が先頭から何ビット目なのかを表記する。 例: 192.168.128.0/24 (ネットワーク部が24ビット目) EC2 EC2とは? Elastic Compute Cloudの略でAWSクラウド上の仮想サーバー。 インスタンスとはEC2から立てられたサーバーのこと。 EC2インスタンスの作成に必要なもの AMI インスタンス起動に必要なOSのイメージ、サーバーのテンプレート。 インスタンスタイプ サーバーのスペックを定義したもの。 例 : m5.xlarge、スペックにより値段が変わる。 ストレージ サーバーにつけるデータの保存場所 EBSとインスタンスストアの2種類ある SSH 通信内容が暗号化された遠隔ログインサービスでEC2にログインする際に使用する。 SSHでログインすることでサーバーと自分のPCを安全に繋いでくれる 公開鍵認証 サーバーの作成者だけがログインできるようにEC2ではSSHログイン時に公開鍵認証を行なっている。 公開鍵と秘密鍵を用いてログイン認証を行う仕組み。 サーバーの作成者(秘密鍵を持っているユーザー)だけがログインできる。 イメージは南京錠で閉めるのは誰でもできるけど開けるには鍵が必要。 ファイアウォール ネットワークを不正アクセスから守るために必要な通信だけ通してそれ以外は通さない機能 AWSではセキュリティグループがファイアウォールの役割を担っている。 Elastic IPアドレス EC2インスタンスのIPアドレスは、起動、停止すると別のIPアドレスが割り当てられてしまう。 Elastic IPアドレスを使用することでIPアドレスの固定ができる。 インスタンスを削除するまでずっとそのIPアドレスを使用できる。 RDS RDSとは? フルマネージドなリレーショナルデータベースのサービス。 AWSが構築や運用の管理をしてくれているのでRDSを使うことでコア機能の開発に注力できる。 MySQLやPostgreSQLなどのデータベースが利用可能。 RDSの特徴として、高い可用性、パフォーマンスの向上、運用負荷の軽減などがある。 Route53 ドメイン インターネット上に存在するコンピューターやネットワークを識別するための名前。 IPアドレスでは覚えにくいので、example.comのような形式で表すインターネット上の住所。 DNS ネームサーバーとフルリゾルバから構成されているドメインの管理システムで、ドメイン名をIPアドレスに変換する。 ネームサーバー ドメイン名とそれに紐ずくIPアドレスが登録しているサーバー。電話帳のようなもの。 フルリゾルバ 紐付くIPアドレスをネームサーバ-に問い合わせて、色々なネームサーバーに聞いて調べて教えてくれるサーバー。 Route53とは? AWSのDNSサービス。ネームサーバーの役割を果たす。 フルマネージドサービスで運用が楽。 ドメインの登録、サーバーの稼働状況をチェックするヘルスチェク、IPアドレスとドメインの紐付けのルーティングを決めるルーティングポリシーなどの機能がある。 IAM IAMとは? AWSのサービスを利用するユーザー権限を管理するサービス。 各AWSリソースに対して別々のアクセス権限をユーザー毎に付与できるので、セキュリティを高めることができる。 ポリシー アクセス許可の定義。 「どのAWSサービスの」「どのリソースに」「どんな権限を」「許可するかしないかを」定義できる。 ユーザー 個々のアカウントのことで、一人一人に一つ一つのユーザーを作る。 グループ IAMユーザーの集合体で、複数のユーザーにアクセス権限を付与。 毎回ユーザー一人一人にポリシーを定義するのは手間だからグループを作りグループにポリシーを割り当てるので、まとめてポリシーを割り当てることができる。 ロール 一時的にアクセスを許可したアカウントを発行できる。 S3 S3とは? 安価で耐久性の高いAWSのクラウドストレージサービス。 S3を使うことでデータ容量を気にすることなく保存することができる。 画像などの静的コンテンツの配信、ログの出力先、静的なWebサイトをS3から公開するなどに利用される。 CloudFront PCとS3の間の仲介に入り高速にコンテンツを配信するサービス。 CloudFrontはPCからS3にリクエストがあった場合、コンテンツを取得してキャシングを行いキャッシュから配信するので、高速化されS3の負荷が減る。 ACM ACMとは? AWS Certificate Managerの略で、AWS上のSSL証明書発行サービス。 簡単かつ安価にSSLの対応、そしてSSL証明書の更新ができる。 SSL証明書 インターネット上でやりとりされるデータの「盗聴」「なりすまし」を防止するための暗号化プロトコル。 SSLを使うことで送受信される情報を第三者に読み取られないように暗号化することができるので、 セキュリティの向上とアクセス権限をもたない人が、サーバーや情報システムの内部に侵入しないようにできる。 ALB ALBとは? Application Load Balancerの略。複数のEC2インスタンスにアクセスを振り分けることで負荷分散でき高い可用性を実現できる。 ACMを利用したSSL/TLS証明書の管理などセキュリティ面が充実している。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby 正規表現を使用して文字列からほしい文字を取得する!! 【gsubメソッド】【sliceメソッド】【scanメソッド】【最短マッチ】

前回の記事で取得したツイートから必要な内容を取得したい!!!と思い正規表現についてググったものをまとめていきます:) 正規表現 正規表現(regular expression)は文字列のパターンを記述するための言語です。また、この言語で記述されたパターンも正規表現と呼びます。 正規表現を用いると、文字列が指定したパターンを含んでいるかどうかを判定し、また含んでいるならばそれが文字列中のどの場所であるかを知ることができます。 Ruby 3.0.0 リファレンスマニュアル > 正規表現 今回取得したツイート このツイートから値段 ブランド アイテム名 を取得したい! 【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in gsubメソッド 文字列中で pattern にマッチする部分全てを文字列 replace で置き換えた文字列を生成して返します。 Ruby 3.0.0 リファレンスマニュアル > gsub このメソッドを使用して、ツイートの段落部分を無くす。 # textにツイート内容を代入する text = "【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in" => "【GUCCI】\nインターロッキングGシルバー\n¥40,700- tax in\n\n【Lansing store】\nアロマキャンドル(4個)\n¥3,000-前後 参考価格\n★フレンチバニラ\n★ガーデニア\n\n【JBL】\nPulse 4\n¥21,780- tax in" # gsubメソッドを使用して段落をなくす irb(main):014:0> text_content = text.gsub(/[\r\n]/,"") => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" sliceメソッド 指定された自身の要素を返します。Array#[] と同じです。 Ruby 3.0.0 リファレンスマニュアル > slice irb(main):001:0> a = "(111)と【222】" => "(111)と【222】" irb(main):002:0> a.slice(/(?<=\().*?(?=\))/) => "111" irb(main):003:0> a.slice(/(?<=\【).*?(?=\】)/) => "222" このような形で取得することができる。 aにはこのように文字列が代入されている。 a = "(111)と【222】" slice.(/(?<=\().*?(?=\))/)で()内の文字を取得している slice.(/(?<=\【).*?(?=\】)/)で【】内の文字を取得している これでいける!!と思ったが複数該当するものがあるとうまくいかないことに気づいた... 前提としてtweet_contentまで代入しておく # textにツイート内容を代入する irb(main):001:0> text = "【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in" => "【GUCCI】\nインターロッキングGシルバー\n¥40,700- tax in\n\n【Lansing store】\nアロマキャンドル(4個)\n¥3,000-前後 参考価格\n★フレンチバニラ\n★ガーデニア\n\n【JBL】\nPulse 4\n¥21,780- tax in" # gsubメソッドを使用して段落をなくす irb(main):014:0> text_content = text.gsub(/[\r\n]/,"") => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" slice(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):015:0> price = text_content.slice(/¥.*-/) => "¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-" slice(/(?<=\【).*?(?=\】)/)を使用して【と】の間の文字を取得する irb(main):016:0> brand = text_content.slice(/(?<=\【).*?(?=\】)/) => "GUCCI" slice(/(?<=\】).*?(?=\¥)/)を使用して】と¥の間の文字を取得する irb(main):017:0> item = text_content.slice(/(?<=\】).*?(?=\¥)/) => "インターロッキングGシルバー" 結果 ・複数当てはまってしまう部分があり、うまくいかない箇所がある ・値段がうまく取得できていない scanメソッド self に対して pattern を繰り返しマッチし、マッチした部分文字列の配列を返します。 pattern が正規表現で括弧を含む場合は、括弧で括られたパターンにマッチした部分文字列の配列の配列を返します。 Ruby 3.0.0 リファレンスマニュアル > scan 該当している文字を複数個取得したいのでscanメソッド使用してみる # 前提としてtext_contentに代入してあるものとする irb(main):044:0> text_content => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" scan(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):045:0> price = text_content.scan(/¥.*-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] scan(/(?<=\【).*?(?=\】)/)を使用して【と】の間の文字を取得する irb(main):046:0> brand = text_content.scan(/(?<=\【).*?(?=\】)/) => ["GUCCI", "Lansing store", "JBL"] scan(/(?<=\】).*?(?=\¥)/)を使用して】と¥の間の文字を取得する irb(main):047:0> item = text_content.scan(/(?<=\】).*?(?=\¥)/) => ["インターロッキングGシルバー", "アロマキャンドル(4個)", "Pulse 4"] 結果 price (値段)だけうまく取得できない 正規表現の最短マッチを使用する 最短マッチについてはこちらを参考にさせていただきました! これで分かった!最短マッチ - Qiita 問題のある部分 scan(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):045:0> price = text_content.scan(/¥.*-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] 1.「+」と「*」の違いについて *から+に変更する *は0文字以上でマッチするのでこの形でもマッチしてしまう。 値段がない時は取得したくない。 irb(main):064:0> text = "インターロッキングGシルバー¥- tax in" => "インターロッキングGシルバー¥- tax in" irb(main):065:0> price = text.scan(/¥.*-/) => ["¥-"] +は1文字以上でマッチするのでこの形でこのようになる。 今回はこっちを採用する! irb(main):067:0> text = "インターロッキングGシルバー¥- tax in" => "インターロッキングGシルバー¥- tax in" irb(main):069:0> price = text.scan(/¥.+-/) => [] 2.「?」を使用する ?を使用することで最短マッチを使用することができる 以下のようにprice = text_content.scan(/¥.+-/)に変更しただけでは根本的な解決にはつながっていない。 irb(main):075:0> text_content => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" irb(main):076:0> price = text_content.scan(/¥.+-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] price = text_content.scan(/¥.+?-/)に変更することでこのように取得することができる:) irb(main):077:0> price = text_content.scan(/¥.+?-/) => ["¥40,700-", "¥3,000-", "¥21,780-"] 結論 +によって 1文字以上を含んでる時にのみ文字を取得し、 ?によって 最短マッチを使用するため¥と-が最短で挟んでいる部分の文字を取得し、 scanメソッドを使用したことにより 複数ある場合は複数取得可能
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】便利な正規表現まとめ

オリジナルアプリ作成にあたり使用した正規表現を、備忘録としてアウトプットします。 英数字混合 ※大文字・小文字の区別なし /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i 半角数字のみ /\A[0-9]+\z/ 全角(漢字・ひらがな・カタカナ) /\A[ぁ-んァ-ヶ一-龥々ー]+\z/ ・ァ-ンではなくァ-ヶとしているのはヴ、ヵ、ヶを含めるため。 ・一-龥ではなく一-龥々としているのは々を含めるため。 ・末尾にーがあるのは「ジュリー」「メアリー」などのハイフンを含めるため。 全角(カタカナのみ) /\A[ァ-ヶー]+\z/ 電話番号10桁以上11桁以下(ハイフンなし) /\A[0-9]{10,11}+\z/ 郵便番号(ハイフンあり) /\A\d{3}[-]\d{4}\z/ 今回登場した正規表現のパターン表記一覧 [a-z]: 角括弧で囲まれた文字のいずれか 1個にマッチ \d:数字にマッチ {n, m}: 直前の文字が少なくともn回、多くてもm回出現するものにマッチ . :改行以外のどの1文字にもマッチ + :直前の文字の1回以上の繰り返しにマッチ \A :直後の文字が先頭にある文字列にマッチ \z :直前の文字が末尾にある文字列にマッチ [ぁ-んァ-ヶ一-龥々]: 角括弧に囲まれたかな、カナ、漢字のいずれかにマッチ(ヴ、ヵ、ヶ、々を含む) ?= :直後に設定した文字が続く文字列にマッチ *? :直前に設定した文字が0回以上続く文字列をチェックし、?の直後の文字が出た段階でその1文字を返す ご指摘などあれば、ご教授いただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]非同期(Ajax)でのコメント機能実装

この記事の目的 非同期処理(ajax)でのコメント投稿機能を学んだのでアウトプットします 目標 要件 コメント投稿は非同期で行う 環境 ・Ruby 2.7.1 ・Rails 5.2.6 前提 ・UserとPostは作成済み ・bootstrapとjquery-railsが入っている 設計 ER図 ルーティング POST /posts/:post_id/comments comments#create GET /comments/:id/edit comments#edit PATCH /comments/:id comments#update DELETE /comments/:id comments#destroy ※ post_idが必要なのはコメントがcreateされる場合だけであり、一度コメントが作成されればそれらコメントは一意のidを持つので、edit,update,destroyの場合はコメントの自身のidのみで特定可能である。 よって、このようなルーティングにする。(shallow: trueで実現可能) このようなshallowルーティングのメリットは、shallowを使わない場合と比較してルーティングがスッキリするという点である。 実装 データベース $ rails g model Comment body:text user:references post:references実行 マイグレーションファイル編集(任意) $ rails db:migrate実行 モデル models/comment.rb class Comment < ApplicationRecord belongs_to :user belongs_to :post validates :body, presence: true, length: { maximum: 1000 } end models/user.rb has_many :comments, dependent: :destroy models/post.rb has_many :comments, dependent: :destroy ※ has_many,belongs_toはメソッドを作るためのメソッド。 ※ Userモデルにhas_many :commentsを記述することで、Userモデルのインスタンスは.commentsメソッドを使い、自身のidに対応するCommentモデルのuser_idを通じて、コメント情報にアクセスできるようになる。Postも同様。 ※ 逆に、Commentモデルにbelongs_to :userを記述することで、Commentモデルのインスタンスは.userメソッドを使い、自身のuser_idに対応するUserモデルのidを通じて、ユーザー情報にアクセスできるようになる。belongs_to :postでも同様。 ルーティング routes.rb resources :posts, shallow: true do resources :comments end ※ 上述したルーティング設計に合わせるため、shallowルーティングを使用している (参考:Railsの”shallow(浅い)”ルーティングを理解する) コントローラー comments_controller.rb class CommentsController < ApplicationController def create @comment = current_user.comments.build(comment_params) @comment.save end def edit @comment = current_user.comments.find(params[:id]) end def update @comment = current_user.comments.find(params[:id]) @comment.update(comment_update_params) end def destroy @comment = current_user.comments.find(params[:id]) @comment.destroy! end private def comment_params params.require(:comment).permit(:body).merge(post_id: params[:post_id]) end def comment_update_params params.require(:comment).permit(:body) end end ※ current_user.comments.findをComment.findにしてしまうと、コメントしたユーザー以外のユーザーがURL直打ちなどによって他人のコメントを編集できてしまうようになるので注意。 ※ ユーザから受け取った情報としてparamsにはないけれども、レコード作成時に追加したい値がある場合はmergeメソッドで含めることができる(今回のpost_id)。 mergeメソッドは、ハッシュ同士を統合できるメソッド。 例 x = {age: "25", email: "tarou@example.com"} {name: "太郎"}.merge(x) #=> {name: "太郎", age: "25", email: "tarou@example.com"} (参考) 【初学者向け】Rails mergeメソッド mergeメソッドについて改めて理解を深めた ※ buildメソッドはnewメソッドと同じ。慣習的に、関連するモデルを生成するときはbuildを使う(参考: railsのnewとbuildの違い) ※ createアクションの処理が終わると、views/comments/ディレクトリ配下にcreate.html.erbまたはcreate.js.erbを探しに行く。edit,update,destroyも同様。 view jsの記述 views/comments/create.js.erb <% if @comment.errors.present? %> alert("<%= @comment.errors.full_messages.join('\n') %>"); <% else %> $('.comments-box').prepend("<%= escape_javascript(render('comments/comment', comment: @comment) ) %>"); $('.input-comment-body').val(''); <% end %> ※ slimならRubyのコードを囲む<%=...%>は#{...}となる ※ escape_javascriptはjと省略して書くこともできる ※ 最初の<% if @comment.errors.present? %>の部分は、ユーザーのコメントがバリデーションに引っかかった場合にエラー文を表示する処理。 ・<% else %>の1行目の部分は、htmlのcomments-boxクラスで囲まれた部分にrender('comments/comment', comment: @comment) をぶちこんでいる。 イメージ <div class="comments-box"> <li>コメント1</li> <li>コメント2</li> <li>コメント3</li> <li>新規コメント</li> ⇦ こいつがjsで追加されるイメージ </div> 検証ツールで実際の挙動を確認 ※ コメントを投稿したとき、画面遷移はせずに<div id="comment-29">...</div>だけが追加されていることがわかる htmlの記述(投稿されたコメントの表示画面) views/posts/show.html.erb(postの詳細画面) ・ ・ ・ <hr> / コメント一覧 <%= render 'comments/comments', comments: @comments %> <hr class="m-0"> <div class="post-comment p-3"> <%= render 'comments/form', post: @post, comment: @comment %> </div> </hr> </hr> views/comments/_comments.html.erb <div class="comments-box"> <%= render comments %> </div> ※ commentsは@comments。つまりrender @commentsで_comment.html.erbに飛ばしているのと同じ(each文省略するやつ) views/comments/_comment.html.erb ( @comments.each do |comment| が省略されている ) (<div class="comments-box">) ・ ・ ・ / コメント一覧のうちのコメントひとつひとつ(|comment|) <div class="col-9"> <span class="font-weight-bold.pr-1"> <%= comment.user.username %> </span> <%= comment.body %> </div> (</div>) htmlの記述(コメントの入力フォーム) views/comments/_form.html.erb <%= form_with model: [post, comment], class: 'd-flex mb-0 flex-nowrap justify-content-between', remote: true do |f| %> <%= f.text_field :body, class: 'form-control input-comment-body', placeholder: 'コメント' %> <%= f.submit '投稿', class: 'btn btn-primary btn-raised' %> <% end %> ※ form_withはデフォルトでremote: trueなので書く必要はないが、local: trueではないことを強調するためにremote: trueを明示。 ちなみにlink_toの場合はremote: trueを必ず書かなければいけない。 ※ ルーティングをネストさせているのでmodel: [post, comment]と2つ書かなければいけない ※ もしform_with model: commentにしたら、/commentsにPOSTリクエストが送られるが、ルーティングのPOST /posts/:post_id/comments comments#createにマッチしないため、post_idが不存在ということでエラーが起きる。 ※ edit, update, destroyについてもcreate同様にviewを作っていく ちなみに、検証ツールを見ればTypeがxhrになっており、form_withのremote: trueが非同期処理をしていることがわかる。 XHR(XMLHttpRequest)とは、JavaScriptなどのウェブブラウザ搭載のスクリプト言語でサーバとのHTTP通信を行うための、組み込みオブジェクト(API)である。 すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。(Wikipedia引用)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git push heroku masterが失敗する

書いた理由 備忘メモ 起こったこと rails tutorialを第3章を進める過程で git push heroku master を実行したとき、コケた remote: We will use "yarn" to install the CLI via "yarn add -D webpack-cli". remote: Do you want to install 'webpack-cli' (yes/no): remote: remote: ! remote: ! Precompiling assets failed. remote: ! remote: ! Push rejected, failed to compile Ruby app. remote: remote: ! Push failed 解決したこと webpack-cliを再インストールしたり、webpackを再インストールした上で、 最終的に再度以下を実行したらできた git commit -am "hogehoge" git push git push heroku master 思ったこと ただ、デプロイを試みる前にコミットをしていなかったため、 対策を打ったつもりが打ててなかった、という状況と思われる。 herokuの理解が足りていないが、コミットしたものしか上げられないものだったのだろう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#1.5 ユーザー編集機能

はじめに 自己学習復習シリーズの#1.5になります。 自己学習の為に記事作成しております。 この記事が誰か1人の役に立ったら幸いです。 今回はユーザー編集機能編です。 ユーザー編集機能作成においてすべき事 users controllerにてeditアクション、updateアクションの作成&ストロングパラメーターの作成 routes.rbにてルーティングの作成 views/usersにedit.html.erbを作成し、編集フォームを作成 マイページや編集ページに遷移できるようにリンクを作成する 以上の4点を行えば、ユーザー編集機能の実装を終える事ができる。 今回は丁寧に、 (1)ルーティングの作成(editとupdate/routes.rbにて)。 (2)editアクションの記述(users controllerにて)。 (3)edit.html.erbにて編集フォームを作成。 (4)updateアクションの記述(users controllerにて)&ストロングパラメーターの作成。 (5)マイページと編集ページにリンク作成。 の順で説明していきます! (1)ルーティングの作成 routes.rb resources :users, only: [:show, :edit, :update] resourcesで作成しているので、そこにeditアクションとupdateアクションのルーティングを作成。 (2)editアクションの記述 users_controller.rb def edit @user = User.find(params[:id]) end (3)edit.html.erbにて編集フォームを作成 users/edit.html.erb <h3><%= @user.name %>さんの編集画面</h3> <%= form_with model:@user, local: true do |f| %> <%= f.label :"名前" %> <%= f.text_field :name %> <%= f.label :"自己紹介" %> <%= f.text_field :introduction %> <%= f.label :"ステータス" %> <%= f.text_field :status %> <%= f.label :"画像" %> <%= f.file_field :image %> <%= f.submit '編集する' %> <% end %> form_withを用いて編集フォームを作成する。 ちなみにこの記述の状態だと、横並びのフォームになっている。 ーーーーーーー以下参考写真ーーーーーーーーーー ーーーーーーーーーーーーーーーーーーーーーーー (4)updateアクションの記述&ストロングパラメーターの作成 users_controller.rb def update @user = User.find(params[:id]) @user.update(user_params) redirect_to user_path(@user) end deviseによって作成されたuserなので、 user_controller.rbにcreateの時に作成されたストロングパラメーターが存在しない。 なので、private内にストロングパラメーターを記述する。 users_controller.rb private def user_params params.require(:user).permit(:name, :image, :introduction, :status) end (5)マイページと編集ページにリンク作成 今のままだと編集ページに遷移できない&編集ページからは編集しないと戻れないので、、 users/show.html.erb : : <%= link_to '編集する', edit_user_path(@user) %> users/edit.html.erb : : <%= link_to 'マイページへ戻る', user_path(@user) %> 最後に 以上でユーザー編集機能の実装が終わりました。 ユーザー編集機能は慣れたら簡単だと思うので、復習を重ねて早く慣れましょう!! 今回も見てくださった方はありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS、EC2でrailsアプリをssl化する!【2021最新版】

まずは参考URLを先に貼り付けておきます。これらを参考にすればうまいことssl化が出来ます! はっきり申し上げます。僕ssl化するだけなのに6時間以上悪戦苦闘しました。 と言うのも、AWSのロードバランサー、ターゲットグループの設定が既存の記事とやることは一緒でも、異なる仕様に変わってしまっているからでした。 なので複数の記事を参考にしてまとめたものをアウトプットしていきます! 前提条件 すでに(http://ドメイン名)でデプロイ済み ssl化の手順の確認 ACMの設定 TGの設定 ELBの設定 セキュリティグループの設定 Route53の設定 リダイレクト処理 ACMの設定 AWSではELB(後で設定します)を利用しているとACM(AWS Certificate Manager)を使用する事ができ、ACMで無料でSSL証明書を利用する事が可能です。 AWSの検索欄でACMを検索し開く 証明書のプロビジョニングを選択 ドメイン名記述 DNSの検証を選択 内容確認をして確定とリクエスト とりあえずこれで発行済みとなればOK! これでssl証明書が発行されました。 TGの設定 ターゲットグループページに遷移 create target groupを選択 instancesを選択 以下のように設定 nextを選択 対象アプリにチェックを入れてinclude...をクリック 最後にcreate target group ELBの設定 ec2のところからロードバランサーを選択 ロードバランサーの製作を選択してさらに「http,https」の項目を選択 必要項目を記述していきます。 Basic configuration Network mappingは「ap-northeast-1a」「ap-northeast-1c」を選択 Security groupsは対象アプリのものを選択(ec2のインスタンスから確認できます) Listeners and routingは先ほど作った「アプリ名-TG」を選択 Create load balancerを選択してELBの作成が完了 作成したELBを選択して、さらにリスナーを選択し、リスナーの追加をする プロトコルポート:「HTTPS」「443」 デフォルトアクション:「アクションの追加」ボタンを選択 「転送先」を選択し、「アプリ名-TG」を選択 セキュリティポリシー:「ELBSecurityPolicy-2016-08」 デフォルトの SSL 証明書:「ACMから(推奨)」「ドメイン名」 保存ボタンを選択 セキュリティグループの設定 ec2の対象インスタンスからセキュリテイグループを選択 インバウンドルールからEdit inbound rulesを選択 以下のように選択 追加する Route53の設定 対象アプリのホストゾーンからAレコードを選択しレコードを編集 エイリアス先をONにして、東京時間、「アプリ名-ELBを選択」に修正する レコードセットの保存をする リダイレクト処理 ロードバランサーに移動 アプリ名-ELBを選択 [リスナー]タブを開く HTTP の[ルールの表示/編集]を選択 以下のように*を記述 (引用:https://dev.classmethod.jp/articles/alb-redirects/) 以下のように記述 (引用:https://dev.classmethod.jp/articles/alb-redirects/) 最後に 以上で完成になります。「https://ドメイン名」で検索してみてください。「http://ドメイン名」でも検索するとリダイレクト処理で「https://ドメイン名」に飛ぶはずですので確認してください。 これするのにまる1日かかったわ。。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む