- 投稿日:2020-03-19T23:50:32+09:00
capistranoでbundle exec cap production deployを実行した時のエラー
何が起こったか?
capistranoを設定して、bundle exec cap production deployを実行して自動デプロイを行おうとしたところ以下のようなエラーに遭遇した。
terminalOpenSSH keys only supported if ED25519 is available (NotImplementedError) net-ssh requires the following gems for ed25519 support: * ed25519 (>= 1.2, < 2.0) * bcrypt_pbkdf (>= 1.0, < 2.0) See https://github.com/net-ssh/net-ssh/issues/565 for more information Gem::LoadError : "ed25519 is not part of the bundle. Add it to your Gemfile." (Backtrace restricted to imported tasks) cap aborted! NotImplementedError: OpenSSH keys only supported if ED25519 is available net-ssh requires the following gems for ed25519 support: * ed25519 (>= 1.2, < 2.0) * bcrypt_pbkdf (>= 1.0, < 2.0) See https://github.com/net-ssh/net-ssh/issues/565 for more information Gem::LoadError : "ed25519 is not part of the bundle. Add it to your Gemfile." Tasks: TOP => rbenv:validate (See full trace by running task with --trace)対処法
以下のgemを追加して、buinle installすると解決した。
Gemfilegroup :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails', '~> 3.6' gem 'capistrano' gem 'capistrano-bundler' gem 'capistrano-rails' gem 'capistrano-rbenv' + gem 'ed25519' + gem 'bcrypt_pbkdf' end以上
- 投稿日:2020-03-19T23:39:20+09:00
[HowTo]ActiveStorage/アバター画像を登録&表示
先日、Active Storageを使用してアバター登録機能を実装しましたので、備忘録として以下に手順などをまとめておきます!
皆様の開発に少しでも役立てていただければ幸いです。Active Storageとは
Active Storageとは、Rails 5.2以降に追加された機能で、ファイルのアップロードを可能にします。
似たような機能でCarrierWaveというものもございますが、こちらは過去に記事にしていたので、
今回はActive Storageを使用することにしました。
https://qiita.com/Tatsu88/items/66374abda7245a006ea0Active Storageの特徴
ActiveStorageはactive_storage_attachmentsとactive_storage_blobsの2つのテーブルを作成します。
アップロードした情報はこれらのテーブルに格納され、モデルと関連づける必要があります。完成イメージ
今回はマイページのアバター実装を目指します。
まず、アバター情報がないときは以下のイメージとなります。マイページ(アバターなし)
登録画面
上記にてアバター情報を登録するとマイページに表示できるようにします。
下準備
ImageMagickとmini_magickのインストール
Active Storageで画像を加工してから(サイズや色など)アップロードするには別のツールをインストールする必要があります。
ImageMagickという画像変換ツールと、それをRailsから使うためのmini_magickというgemをインストールしましょう。ImageMagickのインストール
ImageMagickは、コマンドラインから簡単に画像の保存形式の変更などが行えるツールです。
ターミナルで下記のコマンドを実行してください。ターミナル$ brew install imagemagickmini_magickのインストール
続いて、mini_magickをインストールしましょう。
mini_magickは、Gemの一種なので、Gemfileに記載します。Gemfilegem 'mini_magick'ターミナル$ bundle install #gemを追加したので、必要に応じてrails sは再接続しましょうActive Storageのインストール
上記にて下準備ができましたので、早速Active Storageをインストールしましょう。
ターミナル$ rails active_storage:install #上記で作成したマイグレーションファイルをマイグレートしましょう。(編集は不要です) $ rails db:migrate上記コマンドにて、以下のテーブルが作成され、アップロードした情報はこちらに格納されます。
- active_storage_attachments
- active_storage_blobs関連モデルの編集
上記にてActive Storageの準備ができましたので、続いて関連するモデルを編集しましょう。
今回は"User"モデルに対して、アップロードされた画像情報を"avatar"として紐付けます。/models/user.rbhas_one_attached :avatarview:登録画面
今回は、form_withを使用して情報を登録します。
先ほどモデルに記載した情報をベースに記載します。view(抜粋)= form_with model: @user, url: profile_update_user_path ,method: :patch, local:true do |f| .form-group = f.label :プロフィール写真 = f.file_field :avatar #既に画像設定されている場合は、その内容を削除します。 -if @user.avatar.attached? =@user.avatar.purge .form-group %p.form-group__text--center = f.submit '変更する', class: "btn-default btn-red"view:登録内容表示画面
上記記述にて登録した内容を表示するviewを作成します。
ポイントとしては、アバター画像がある場合とない場合で表示する画像を分けてます。
アバター画像の有無は".attached?"メソッドを使用してます。
nil?やblank?やpresent?を使うとうまくいかないので、ご注意ください。view(抜粋).mypage_top_container .mypage_top_container_avator .mypage_top_container_avator_main -if @user.avatar.attached? =image_tag @user.avatar, class:"avatar" -else =image_tag ("noimage.png"),class:"avatar"以上で設定したアバター画像を表示することができます!
その他、コントローラやルーティングなど準備は必要となりますが、各自設定によると思われますので、
今回は割愛させていただきます。参照
Active Storage の概要
https://railsguides.jp/active_storage_overview.html【Ruby入門】真偽判定present?の使い方をわかりやすく解説
https://www.sejuku.net/blog/66030[Rails5.2]ActiveStorageの仕組み(図あり)と使ってみてわかったこと
https://qiita.com/eightfoursix/items/a47ce1bd945582f5d808【Rails】image_tagの使い方を徹底解説!
https://pikawaka.com/rails/image_tagActiveStorage で画像を複数枚削除する方法
https://h-piiice16.hatenablog.com/entry/2018/09/24/141510Active Strageを使用してユーザーのアバターを登録、表示する
https://re-engines.com/2018/03/12/active-strage%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E3%82%A2%E3%83%90%E3%82%BF%E3%83%BC%E3%82%92%E7%99%BB%E9%8C%B2%E3%80%81%E8%A1%A8%E7%A4%BA/以上となります。最後までご覧いただき、ありがとうございました!
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします!
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。
- 投稿日:2020-03-19T23:31:15+09:00
インクリメンタルサーチで追加済みユーザーが検索されないようにする
目的
チャットアプリのグループメンバー追加ページを以下の仕様で作成する。
- インクリメンタルサーチでメンバー検索をして登録リストに表示
- 登録リストに表示されたメンバーを登録ボタンで追加リストに登録
- 登録されたメンバーは登録リストに表示されない問題点
登録されたメンバーが登録リストに表示されてしまう。
考え方
検索されたメンバーのIDが追加リストに登録されたメンバーのIDと重複しない場合のみ表示させれば良い。
コード
before.jsusers.forEach(function (user) { if (user.id) { addUser(user); } })after.jsusers.forEach(function (user) { let idNum = document.getElementById(user.id); if (user.id && !idNum) { addUser(user); } })
- 投稿日:2020-03-19T22:30:03+09:00
Railsで、どちらか一方のカラムを入力必須(二者択一)にするバリデーション
はじめに
Ruby on Rails で どちらか一方のカラムを入力必須にするバリデーションについて書きます。
具体的な例をあげると、ユーザーモデルの
phone
、どちらか片方だけに必ず値が入るようにバリデーションします。両方に値が入っている場合もNGです。要件に合わなかったバリデーション
ググって下記のようなバリデーションを見つけましたが、両方入力した場合にバリデーションを通ってしまうので、要件には合いません。
app/models/user.rbclass User < ApplicationRecord # phoneが空ならば、emailを必須にする validates :email, presence: true, unless: :phone? # emailが空ならば、phoneを必須にする validates :phone, presence: true, unless: :email? endUser.create!(name: "たなか", email: "test@example.com", phone: "08011112222") => #<User id: 1, name: "たなか", email: "tanaka@example.com", phone: "08011112222", created_at: "2020-03-19 12:29:20", updated_at: "2020-03-19 12:29:20">要件にあったバリデーション
要件を満たすために、次のカスタムバリデーションを作成しました。
app/models/user.rbclass User < ApplicationRecord validate :required_either_email_or_phone private def required_either_email_or_phone # 演算子 ^ で排他的論理和(XOR)にしています # emailかphoneのどちらかの値があれば true # email、phoneどちらも入力されている場合や入力されていない場合は false return if email.present? ^ phone.present? errors.add(:base, 'メールアドレスまたは電話番号のどちらか一方を入力してください') end endUser.create!(name: "たなか", email: "tanaka@example.com", phone: "08011112222") # => ActiveRecord::RecordInvalid (バリデーションに失敗しました: emailまたはphoneのどちらか一方を入力してください) User.create!(name: "たなか", email: nil, phone: nil) # => ActiveRecord::RecordInvalid (バリデーションに失敗しました: emailまたはphoneのどちらか一方を入力してください) User.create!(name: "たなか", email: "tanaka@example.com", phone: nil) # => <User id: 2, name: "たなか", email: "tanaka@example.com", phone: nil, created_at: "2020-03-19 13:06:55", updated_at: "2020-03-19 13:06:55">おわり
普段は論理和
||
演算子 か論理積&&
演算子 ばかりで、^
演算子は使わないので、上記のコードを思いつくまでに時間をかけてしまいました…!
- 投稿日:2020-03-19T21:27:47+09:00
EC2サーバで生成した公開キーはどこからどこまでなのか
- 投稿日:2020-03-19T20:28:35+09:00
チーム開発 3/19
メモです
最終課題二日目
トップページを担当検索機能をつける際に検索ボタンを画像に引っ付けたい
https://teratail.com/questions/60004
参考サイト
button_tagもしくはimage_submit_tagを使うと解決画像の大きさを自由に変えた(ブロックに合わせた大きさ)
https://qiita.com/jag_507/items/79af40e12a2e50bbc04e
https://teratail.com/questions/39407
参考サイト
まず大きさを変えたい画像のimgにクラスをつける
そこに
max-width: 100%;
height: auto
を記述する検索機能にクラスを書きたいがエラーが出た
多分form_tagの書き方が悪い
form_withで解決したFormにcssの要素をつけたい
form{}で要素をつけれるhtml li リストマーク(・)消す方法
list-style: none;ブロック全体に画像を貼る時に使う
background-image: url(pict/bg-mainVisual-pict_pc.jpg)まとめ(全体)
トップページ
部分テンプレート完成デバイス
サーバーサイドの新規は完成
見た目も90%ほど完成マイページ
ビューを作りました
サイドバーの中身をみんなで考えたいです商品の出品ページ
見た目のみ
- 投稿日:2020-03-19T20:20:41+09:00
定義してないのになぜか使える activated? admin? メソッド Ruby on Rails チュートリアル
こんなメソッド定義してないぞ?と思いきや、
Railsでは真偽値をとるカラムであれば、モデル.カラム名?で真偽値を取得できるらしいです。>> user = User.first User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Example User", email: "example@railstutorial.org", created_at: "2020-03-15 10:30:06", updated_at: "2020-03-15 10:30:06", password_digest: "$2a$10$XvC6suqKbRRIHIm8nQOyjeQcKJixPXdm1b331TQJ7y5...", remember_digest: nil, admin: true, activation_digest: "$2a$10$5/9pDzSQIJdzpaAbFCJZO.qptq0BYtnH.Q/sBwP5epB...", activated: true, activated_at: "2020-03-15 10:30:06"> user.admin? =>true user.activate? =true
- 投稿日:2020-03-19T19:58:27+09:00
初めてのbootstrap導入(rails)
はじめに
bootstrapを導入する時に手間取ってしまったので、初めてbootstrapを触ってみる人でもわかりやすく、導入手順を一からおさらいします超初級編です
① Gemfileの末尾にbootstrapを追加
Gemfilegem 'bootstrap'今回はバージョン指定はしません。
この時、compass-railsというgemが追加されてあるとエラーを吐いてしまうので、なくて問題ないようなら削除します。② gemの更新
terminal$ bundle install③ application.cssにbootstrapを導入
app>assets>stylesheet>application.css
application.css@import "bootstrap";application.cssをapplication.scssに名前変更
④ application.jsにもbootstrapを適用
app>assets>javascripts>application.js
application.js//= require bootstrap⑤ bootstrapを挿入
bootstrapから、好きなデザインを探し、適応させたいビューファイルに挿入します。
bootstrapトップページから、ヘッダーのDocumentation->左にあるCommponentsから探します。e.g.) 今回は、headerにNavbarを使います。
app>views>layouts>application.html.erb
application.html.erb<header> ここにコピーしたコードを貼り付け </header>これでサーバーを起動させて該当ページを表示させると、下のようにbootstrapが適用されます。
後はエディタのbootstrapをコピーした部分のリンクや表示させたい文字などを調節して完成です!やったね!
- 投稿日:2020-03-19T18:20:43+09:00
RailsのformにAjaxを実装する前提
RailsにjQueryを使ったAjaxを適用するために色々調べました。
個人的な備忘録として残します。configを設定
config/application.rbrequire File.expand_path('../boot', __FILE__) module SampleApp class Application < Rails::Application config.action_view.embed_authenticity_token_in_remote_forms = true # 追加 end endコントローラーの変更
class HogesController < ApplicationController def hoge respond_to do |format| format.html redirect_to hoge_path format.js # ※下 end end end※ renderで指定しなければ
アクション名.js.erb
を探すテンプレートの変更
form_with
を使っている場合(推奨)
remote
はデフォルトでtrueのでやることなし
(falseにしたい場合はlocal: true
を追加)app/view/hoges/hoge.html.erb<div id="ajax-test"> <%= form_with ... do |f| %> <%= f.submit "hogehoge" %> <% end %> </div>
form_for,
form_tag
を使っている場合、オプションに
remote: true
を付ける。app/view/hoges/hoge.html.erb<div id="ajax-test"> <%= form_for ..., remote: true do |f| %> <%= f.submit "hogehoge" %> <% end %> </div>コントローラーで
render
しなかった場合、以下の点に注意してファイル.js.erb
を追加
・適用したいテンプレートと同じ場所に配置
・ファイル名はコントローラーのアクション名と同じ名前に設定app/view/hoges/hoge.js.erb$("#ajax-test").html("<%= 'さあ、遠慮なく私をhogeりなさい!' %>");記述はjQueryで。
.html("...");
の部分を
.html("<%= escape_javascript(render('hoges/hoge')) %>");
.html("<%= j ( render('hoges/hoge') ) %>");
でも可
などとすると色々できる。
- 投稿日:2020-03-19T16:50:24+09:00
redis-railsのセッション有効期限の挙動を確かめて遊ぶ
redis-railsのセッション有効期限の挙動をチェック
ローカルでサイトにアクセスすることで3ヶ月の期限付きセッションデータが生成される設定をしている。
redisを起動
commandredis-cliDB1を選択する(設定によって変わります)
redis-commandsselect 1サイトにアクセス、キー一覧を取得。
=>1件のデータが作られている【有効期限を無期限にするとどうなる?】
再度サイトにアクセス
- データは1件しかないので、セッションは新規に作られた訳ではない
- 有効期限が無期限(-1)になり、過去のセッション情報が更新されたことがわかる
【有効期限を60秒に変更してみた】
再度変更後サイトにアクセス
- 先ほど、無期限に設定したセッションデータの有効期限が60秒に更新された
- 徐々に秒数のカウントが減っていき、最後は-2(データ見つからない)になりました。
複数のユーザーがいる場合の挙動はどうなる?
プライベートブラウザと通常のブラウザの2種類を用いて、2種類のセッションを作成した
【有効期限を60秒に変更し片方だけサイトにアクセスする】
サイトにアクセスしたセッションは有効期限が更新され、60秒後には消えることになった。
アクセスしていない方は残り続けている。片方のセッションは60秒が経過し、削除されました
- 投稿日:2020-03-19T14:42:42+09:00
Ruby on Rails チュートリアル学習記録 第6章
第4、5章については特に書く内容がなかったため学習記録は付けませんでした
6.1
特になし
6.2
特になし
6.3
heroku run rails db:migrate
をbash: heroku: command not found
というエラーメッセージ。
3章の時と同じ方法で解決
nvm install node
npm install -g heroku-cli
を実行後、あらためてheroku run rails db:migrate
を実行6.4
特になし
- 投稿日:2020-03-19T14:21:01+09:00
【Rails】フレンドリーフォワード
フレンドリーファワード
ログインしていないユーザーが編集ボタンをクリックする際に、ログイン後にトップページではなく編集ページに飛ぶようにしたい。
そういった機能を追加できるのがフレンドリーフォワードです。実装
sessions_helper.rbdef store_location session[:forwarding_url] = request.original_url if request.get? endusers_controller.rbdef logged_in_user unless logged_in store_location flash[:danger] = "please login" redirect_to login_url end endユーザーのログイン時にフレンドリーフォワードを実装するにはセッションヘルパーに
store_location
を定義し、users_controller.rb
にてlogged_in_user
メソッドを定義します。まず
logged_in_user
でユーザーがログインしていない場合にstore_location
を実行させ、現時点のURLをsession[:forwarding_url]
に保存します。
original_url
はhttp(s)以外も扱えるよう指定しています。
request.get?
でGETリクエストの時だけ値を格納しているように指定しているのは、ログインしていないユーザがフォームで送信した場合にurlを転送先に保存させないためです。sessions_helper.rbdef redirect_back_or(default) redirect_to(session[:forwarding_url] || default) session.delete(:forwarding_url) end def store_location session[:forwarding_url] = request.original_url if request.get? endsessions_controller.rbdef create @user = User.find_by(email: params[:session][:email].downcase) if @user && @user.authenticate(params[:session][:password])true log_in @user params[:session][:remember_me] == '1' ? remember(@user) : forget(@user) redirect_back_or @user else flash.now[:danger] = 'Invalid email/password combination' render 'new' end endそしてセッションヘルパーに
redirect_or_back
メソッドを追加し、sessions_controller.rb
のcreateアクション
にてredirect_back_or @user
を追記します。
session[:forwarding_url] || default
でsession[:forwarding_url]
の値がnillだった場合にdefault
になるようになっています。
session.delete(:forwarding_url)
ではログイン後に指定のパスに移動した後に:forwarding_url
を削除するようにしています。
こうすることで次回ログインした時に保存していたURLに飛ぶことを防いでいます。上記手順でフレンドリーフォワードを実装できました。
- 投稿日:2020-03-19T13:38:08+09:00
elasticbeanstalkにcronoを設定したので、そのconfig
Elasticbeanstalk + rails + crono
railsでcron的なものを使いたかったけど、crontabを触りたくなかったので、cronoを使うことにした.その設定ファイル(結構作るのに時間かかったので。。。)
Cronoはこちら
I would like to use something like cron with rails, but didn't want to use crontab, so I try to use crono(I know it may not be maintained, but...), here is the config which I used.環境
# rails -v Rails 6.0.2.1 # uname -a Linux ip-172-31-27-188 4.14.165-103.209.amzn1.x86_64 #1 SMP Sun Feb 9 00:23:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux設定ファイル
# cat .ebextensions/05_crono.config commands: create_post_dir: command: "mkdir -p /opt/elasticbeanstalk/hooks/appdeploy/post" ignoreErrors: true files: "/opt/elasticbeanstalk/hooks/appdeploy/post/50_restart_crono.sh": mode: "000755" owner: root group: root content: | #!/usr/bin/env bash EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir) EB_APP_PID_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_pid_dir) EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user) EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir) . $EB_SUPPORT_DIR/envvars . $EB_SCRIPT_DIR/use-app-ruby.sh PID=$EB_APP_PID_DIR/crono.pid cd $EB_APP_DEPLOY_DIR if [ -f $PID ] then su -s /bin/bash -c "kill -TERM `cat $PID`" $EB_APP_USER su -s /bin/bash -c "rm -rf $PID" $EB_APP_USER fi . $EB_SUPPORT_DIR/envvars.d/sysenv sleep 10 su -s /bin/bash -c "bundle exec crono start -P $PID " $EB_APP_USER "/opt/elasticbeanstalk/hooks/appdeploy/pre/03_mute_crono.sh": mode: "000755" owner: root group: root content: | #!/usr/bin/env bash EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user) EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir) . $EB_SUPPORT_DIR/envvars . $EB_SCRIPT_DIR/use-app-ruby.sh PID=$EB_APP_PID_DIR/crono.pid if [ -f $PID ] then su -s /bin/bash -c "kill -USR1 `cat $PID`" $EB_APP_USER fiテストに使ったjob
class CronoTestJob < ApplicationJob queue_as :default def logger Crono.logger.nil? ? Rails.logger : Crono.logger end def perform(*args) logger.info '*** start crono test job ***' end end
- 投稿日:2020-03-19T12:58:05+09:00
railsのGravatarで表示するデフォルト画像を変更する
いきさつ
Railsのチュートリアルを進めていた時に、Gravatarを用いてユーザのプロフィール画像を設定していました。その際、
「デフォルト画像をもう少しオシャレにできないものか」
と思ったので、Gravatarのデフォルト画像変更方法について調べました。
ちなみにデフォルト画像は以下の通りです。
Gravatarとは
画像をアップロードし、指定したメールアドレスと画像を関連づけることができる無料のサービスです。
チュートリアルでは、ユーザの画像を指定をするコードは以下の通りになっていると思います。users_helper.rbdef gravatar_for(user, options = { size: 80 }) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) size = options[:size] gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}" image_tag(gravatar_url, alt: user.name, class: "gravatar") endそれぞれのユーザの画像は、表示する画像のURLを指定するgravatar_urlに依存します。
gravatar_urlのパラメータ
今の段階では、表示する画像のURLとして
https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}
が指定されています。
このパスの指定に何かヒントがありそうです。公式サイトにあったこちらの記事によると、If you'd prefer to use your own default image (perhaps your logo, a funny face, whatever), then you can easily do so by supplying the URL to an image in the d= or default= parameter. The URL should be URL-encoded to ensure that it carries across correctly, for example:<img src="https://www.gravatar.com/avatar/00000000000000000000000000000000?d=https%3A%2F%2Fexample.com%2Fimages%2Favatar.jpg" />
とのこと。つまり、URLのdまたはdefaultというパラメータに設定したいパスを指定することで、任意の画像をデフォルト画像に指定できるとのこと。
ただし、以下の制約があります。MUST be publicly available (e.g. cannot be on an intranet, on a local development machine, behind HTTP Auth or some other firewall etc). Default images are passed through a security scan to avoid malicious content.
MUST be accessible via HTTP or HTTPS on the standard ports, 80 and 443, respectively.
MUST have a recognizable image extension (jpg, jpeg, gif, png)
MUST NOT include a querystring (if it does, it will be ignored)
- 誰もがアクセス可能な画像であること(公開範囲を限定している画像やローカル環境にある画像はNG)。
- HTTP, HTTPSのポート番号がそれぞれ80番、443番であること。
- 拡張子がjpg, jpeg, gif, pngのいずれかであること。
- パスにURLパラメータを用いないこと。 だそうです。
実際にやってみる
現段階では、ユーザの一覧画面は以下の通りです。
デフォルト画像として、先ほどお見せした水色の画像が設定されています。
こちらの記事によると、例えばdのパラメータにrobohashを指定すると、以下のようなロボットの画像がデフォルト画像になるようです。
実際にuser_helpers.rbを以下のように変更します。gravatar_urlのdにrobohashを設定しました。users_helper.rbdef gravatar_for(user, options = { size: 80 }) gravatar_id = Digest::MD5::hexdigest(user.email.downcase) size = options[:size] gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?d=robohash&?s=#{size}" image_tag(gravatar_url, alt: user.name, class: "gravatar") endすると
確かにデフォルオ画像がロボットになりましたね。
別の画像も試してみます。参考文献の記載にしたがって、次はdにretroを指定します。gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?d=retro&?s=#{size}"
デフォルト画像がドット絵になりました。
最後に、こちらの画像を試してみます(特に悪意はありません)。
dに画像のURLを指定します。gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?d=https://resizer6.myct.jp/img/79313116268/otaku_winter.png&?s=#{size}"まとめ
Gravatarのデフォルト画像は、dというパラメータに画像のパスを指定することで変更することができます。
参考文献
- 投稿日:2020-03-19T12:30:37+09:00
Rails5 slim 掲示板やトピック等でのtextの表示形式
掲示板を実装した時に改行やスペース、URLの反映がちょっと手間取ったのでメモ
ユーザーがフォームで入力したtextを取得して掲示板に表示させる時何も設定していないと改行等全く反映されない。
コピペしたURLも文字列として扱われてリンク表示にならないです。あとスペースも反映されない。
-require 'uri'
- @board.comments.each do |comment|
| >
= simple_format(text_url_to_link(h(comment.content.gsub(/ /, ' ').html_safe)), {}, sanitize: false)上記の記載で私の場合は解決できました。
require 'uri
と
simple_format(text_url_to_link(h(comment.content.gsub(/ /, ' ').html_safe)), {}, sanitize: false)
がキモ。それぞれの意味についてはググれば出てきます。
この記載で「改行、半角スペース、全角スペース、URLリンク」が全て反映されるようになりました。
- 投稿日:2020-03-19T12:19:03+09:00
Rails5 slim bootstrap4 placeholderの反映
- 投稿日:2020-03-19T11:52:40+09:00
【Rails/Ruby】クラスメソッドとインスタンスメソッドの使い分け
「クラスメソッドとインスタンスメソッドの使い分けについて教えてください」
って前に聞かれてちょっと困ったことを思い出したのでまとめてみました~???※クラス・インスタンスの概念の説明やクラスメソッド・インスタンスメソッドの詳しい説明は端折ってます~!
クラスメソッド
・クラスに対して使う
例:newメソッド/など# インスタンスの生成 Animals.new・DBからデータを取得したり保存するときに使う
例:allメソッド/findメソッド/createメソッドなど# 引数に一致するデータをDBから取得する User.find(1)・外部ファイルやサイトからデータを取得する(データを取得し、インスタンスを作成する)ときに使う
例:スクレイピングなど・全体で扱うべき情報を扱うときに使う
例:投稿の総数などインスタンスメソッド
・生成した個々のインスタンス(投稿1つ1つ、ユーザー1人1人など)に対して使う
例:update/destroy/eachなど# userにインスタンスを代入 user = User.find(1) # userに代入したデータを削除する user.destroy最後に
個人的にわかりやすいと思ったクラスとインスタンスの説明で終わります~!
クラス = 野菜という大枠 インスタンス = ニンジン・オクラ・ブロッコリーなど細かな種類クラスとインスタンスの概念って理解するのってやっぱり難しいですね?
- 投稿日:2020-03-19T10:14:03+09:00
チーム開発 3/18
メモで
最終課題1日目
ER図法
テーブル、カラム、タイプ、オプション
ターミナル
Bundle install
Rails s問題:Git hubでmasterに記入するが共有されない
解決? :Masterに記述する場合は親に当たる人(masterを作った人)が書かないと共有されないかも?
セッティングで招待?しないと共有されない問題:親じゃない人がプルリクエストした場合にその人がマスターのブランチに戻した時に
記述したところが消えてしまう前のところのまま更新されていない?
変なエラー?プルリクエストとした後にセッティングした時におかしくなった?
一回招待を取り消してみて再招待してみる
ファイルが消えてしまったためもう一度git cloneしていく
やり直し
解決:やり直し☑️環境設定
ER図法を提出
問題点、修正点を探す
宅配のアドレスにカラムは1つで十分
サイズのテーブルを消してユーザーに書いてもらう形にする、ユーザーのテーブルにカラムとして追加まとめ 次どうするか
トップページを二人でやる
トップページは金曜日
ユーザーのログインページ1人だと厳しいかも
新規登録が大変
テストもある誰が何をするかを決める
__________________________________________________________
調べた事
●Desktopのブランチ消す時は上のバー(アップルのマークある方)にブランチとあるのでそこのデリートで消せる
●has_one
従属する側のモデルに belongs_to を記述し、
従属させる側のモデルに has_one を記述する。
1体1の関係の時使うかも?
かってにidを取って来てくれる
belongs_toも一緒
- 対象を1つ持っているなら、has_one
- 対象を複数持っているなら、has_many
- 自分が対象に所属しているなら、belongs_to ●clear fix https://qiita.com/mariofujisaki/items/2ad1de8432d7249afadc 参考ページ Flootを使った時に浮いて回り込んでしまったのを防ぐ ●mixing @mixin に続いてお好みの名前を定義し、@include で呼び出します。何度も使うようなスタイルがあるなら、あらかじめ定義しておくと便利です。 https://www.webcreatorbox.com/tech/sass-mixin 参考ページ
- 投稿日:2020-03-19T05:48:06+09:00
bootstrap3から4への移行方法について (Rails5)
今回はbootstrapのバージョン変更について書いていきたいと思います。
経緯はこうです。ポートフォリオ製作の中、週一の専用メンタリングがあり時間もわずかのところでメンターの方から
『あれ?bootstrapは3を使ってるんですね!』
な、なんだ!? 教材を参考にして制作を進めてるからそもそもバージョンにこだわりがなくてbootstrap3になっていたわけだが何かまずいのかな?と聞いてみると
『今はbootstrap4が主流ですね。特にこだわりがなければ新しいのを使った方がいいですよー。あとは今であれば困ったときにbootstrap4の方が似たようなケースも多いと思うので解決しやすいですよ!!』
なるほど。そしたらどうせ今後も使う機会もあると思うので新しいbootstrap4にバージョンを変更しよう!!
と意気込み、以下の記事を参考にしながらやってみました。
https://qiita.com/NaokiIshimura/items/c8db09daefff5c11dadf
なんだー簡単じゃんと思い いざアプリを立ち上げると
全然導入できねえ
こんなにバージョン更新が難しいとは。。。
やったこと
gemfile中に以下を記述しbundle install
gem 'bootstrap', '~> 4.1.1' gem 'jquery-rails'sprockets-railsがv2.3.2.以上である必要があるらしいので以下コードでバージョン確認
$ bundle show |fgrep sprockets-rails * sprockets-rails (3.2.1) 問題なしapp/assets/stylesheets/application.scssの中に@import "bootstrap";があることを確認。またファイル名がcssのままだとよくないのでscssに変えておく
ここも今までのbootstrap3導入まででやっていたことなので問題なし。
ブートストラップJavaScriptはjQueryに依存しています。Rails 5.1以降を使用している場合は、
jquery-rails
gemをGemfileに追加します。gem ' jquery-rails ' ここもbootstrap3導入まででやっていたことなので問題なし。application.jsに以下を記述する。
//= require jquery3 //= require popper //= require bootstrap-sprocketsrails s を再度して立ち上げる
エラー発生
内容をググりながらみていくと
Sass::SyntaxError in Pages#index
シンタックスエラーなのでコンパイルがうまくいってないのかな?
念のため他のページで読み込んでみるも特にエラー内容は変わらず
File to import not found or unreadable: bootstrap-sprockets.
この一行で検索をかけるとhttp://geekday.hatenablog.com/entry/2017/03/31/021052同じような境遇の方がいたので早速みてみるも解決せず
タイポもなさそうだしバンドルインストール後railsサーバー再起動するも変わらずエラーhttps://github.com/twbs/bootstrap-rubygem
bootstrap4の公式手順を見るも特にやってないことはないんだけどなあと途方に暮れました。まじで
ここから解決方法!!!
というわけでメンターの方に助けを求めると
まずGemファイル内のgem 'bootstrap-sass'を削除した方がいいと
これはbootstrap3を導入するときの記述なので本質的なエラーとは関係ないかもしれないが余計な影響があるかもしれない
このエラー画像の下の赤いラインなんですが
@import "bootstrap-sprockets";
app/assets/stylesheets/application.scssの中にbootstrap3の名残で書いていたのですが、これがそもそもbootstrap4では必要がないらしいです なのでこれを削除@import "bootstrap-sprockets"; File to import not found or unreadable: bootstrap-sprockets.とエラーメッセージが出ているのでこちらのファイルがないのに読み込みにいってます。 なので余談ですがapp/assets/stylesheets/application.scssの中に適当なファイル名を追記すると同じエラーが出ました。(@import "aaaaa";実際にこんなファイルはないので読み込めないですと表示されます)
再度railsサーバー再起動すると無事に表示!!
3から4に変えたことでデザインは崩れていましたが。そもそも
いやーここまで長かった。スタックオーバーフロウの英語の記事もGoogle先生に翻訳してもらいながら他の関係ありそうな記事を何件も読み半日以上格闘してました。
今回も残念ながら一人での解決はできませんでしたが惜しいところまで来ていたかと思います。
今後のエラー解決方法としては
バージョンを変える場合は以前のバージョンと更新したいバージョンの公式説明を読んでみる
これに関しては4の導入説明は読んでいたけど3の導入説明は探していなかったので3の記事を読んでいたら導入方法の違いがわかってもしかしたら解決できたかもしれません。更新手順を進める前にgitにpushしてからいろいろ変更しても大丈夫なようにすれば気軽に怪しい場所を削除して解決できるかなと思いました。
ニッチではありますが同じ境遇で同じエラーで困っている方は是非参考にしてください。
- 投稿日:2020-03-19T04:34:42+09:00
【Rails】 SCSS で Bootstrapライクな opacity-n(透過) を追加する
何をするの??
CSSでオブジェクトを透過したいときに、
opacity-85
みたいなBootstrap
ライクに指定したかったので
SCSS
を使って追加しちゃいますSCSS の記述?
SCSS
ファイルに以下の記述を追加するだけで、
opacity-0
= 0% (透過) からopacity-100
= 100% (非透過) まで全ての透過度を可変でCSSセレクタ
としてつかうことができますopacity.scss@for $i from 0 through 100 { .opacity-#{$i} {opacity: $i * 0.01;} }some.erb.html<div class="opacity-62"> # 62%の透過になる </div>ファイルとして実装する方法(おまけ)
アセットパイプラインで実装する場合 ?
application.scss
▶opacity.scss
の順にロードされるように配置する/app/assets/stylesheets/application.scss*= require_tree . // もしくは *= require_tree opacity/app/assets/stylesheets/opacity.scss@for $i from 0 through 100 { .opacity-#{$i} {opacity: $i * 0.01;} }webpacker で実装する場合 ?
application.js
▶application.scss
▶opacity.scss
の順にロードされるように配置する
追加位置はいずれも後ろの方でOK/app/javascript/packs/application.jsimport "../stylesheets/application";/app/javascript/stylesheets/application.scss@import "opacity";/app/javascript/stylesheets/opacity.scss@for $i from 0 through 100 { .opacity-#{$i} {opacity: $i * 0.01;} }
CSS も量が多くなったら別ファイルに分けると、見通しが良いですね?
- 投稿日:2020-03-19T02:11:42+09:00
ec2をターミナルで操作するときに詰まった話(fatal: Could not read from remote repository.)
(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
を参考に、AWSにrailsアプリをあげようとしていたときの凡ミスについて。エラー箇所について
上記の記事で
[~]$ ssh mumu_key_rsaでログインした後に、
[ユーザー名|~]$ vim .gitconfigで、諸々の設定を記述するところがある。
そこで、記事通り、下記のように設定すればよかった。
[user] name = your_name (#gitに登録した自分の名前) email = hoge@hoge.com (#git登録時の自分のメアド) [alias] (#これはお好きに) a = add b = branch ch = checkout st = status [color] (#色付け) ui = true # githubの場合 [url "github:"] (#pull、pushのための設定) InsteadOf = https://github.com/ InsteadOf = git@github.com:しかしながら、筆者は
[user] name = your_name (#gitに登録した自分の名前) email = hoge@hoge.com (#git登録時の自分のメアド) [alias] (#これはお好きに) a = add b = branch ch = checkout st = status [color] (#色付け) ui = true # githubの場合 [url "github:"] (#pull、pushのための設定) InsteadOf = https://github.com/(ここに実際にcloneしたいアプリのレポジトリURLを書いていた) InsteadOf = git@github.com:(ここに実際にcloneしたいアプリのレポジトリURLを書いていた)上記を見ていただければ分かる通り、無駄にレポジトリURLを記載してしまっていた。
その結果、git cloneでfatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.と、言われてしまったのだった。
まとめ
(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
この記事では、丁寧にコメントでここには○○を記述などと書いてくれている。
それをちゃんと読んでいなかった筆者は簡単な設定ミスで結構苦労した(3時間も使ってしまった)。
みなさんが、そして未来の自分が再びこんな凡ミスを犯さないためにも、備忘録的に書かせていただきました。
- 投稿日:2020-03-19T01:32:33+09:00
マイグレーション操作
はじめに
「Ruby on Rails 5 速習実践ガイド」の本の内容(Chapter4-1)に沿ってまとめと、他に調べて知ったことも書いてみようと思います。
(内容薄いですが、、、、)Ruby on Rails 5 速習実践ガイド(Chapter4-1)
?マイグレーションの適用
2つのステップ
マイグレーションは基本的に2つのステップで行います。
1. Rubyのコードで、データベースのスキーマを変更するファイル、 「マイグレーション」ファイル を作成する
2.rails db:migrate
コマンドで、作成した「マイグレーション」ファイルをデータベースに適用する1つのマイグレーションは1つのバージョン
1つのマイグレーション(ファイル)が、 1つのバージョンとして、扱われます。
マイグレーションファイルを作成しただけでは、データベースは変更されず(バージョンは上がらず)、マイグレーションファイルを適用するとデータベースが変更されます。
マイグレーションを取り消す(バージョンを下げる)にも、マイグレーションファイルを削除するだけでは変更されないため、取り消すコマンドを実行して、操作を適用します。?バージョンの上げ下げ
下のマイグレーションファイルは、Userテーブル作成し、nameカラムとemailカラムを持つことを記述されています。
changeメソッド
の中に、「Userテーブルを作成する」というコードが書かれていれば、
マイグレーションの適用を取り消す際には、「Userテーブルを削除する」というコードが書かれているかのように処理をしてくれます。db/migrate/[timestamp]_create_users.rbclass CreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| t.string :name t.string :email t.timestamps end end endこちらのマイグレーションファイルは、nameカラムに入る文字列の長さを制限しています。
upメソッド
にバージョンを上げる処理、downメソッド
にバージョンを下げる処理を記述しています。db/migrate/[timestamp]_change_users_name_limit10.rbclass ChangeUsersNameLimit10 < ActiveRecord::Migration[6.0] def up change_column :Users, :name, :string, limit: 30 end def down change_column :Users, :name, :string end end?schema.rbについて
Railsは、データベースの構造(スキーマ)を
db/schema.rb
というファイルに自動で出力します。
テーブル、カラムの構造を確認できます。Railsガイドには、このように書かれています。
Railsのマイグレーションは強力ではありますが、データベースのスキーマを作成するための信頼できる情報源ではありません。
信頼できる情報源は、やはりデータベースです。Railsは、デフォルトでデータベーススキーマの最新の状態のキャプチャを試みるdb/schema.rbを生成します。?主なコマンド
migrationまわり
migrationに関する主なコマンドまとめです
コマンド 意味 bin/rails db:migrate 最新までマイグレーションを適用する bin/rails db:migrate VERSION=20200319 特定のバージョンまでマイグレーションが適用されていた状態にする bin/rails db:rollback バージョンを1つ戻す bin/rails db:rollback STEP=2 バージョンを指定したステップ数だけ戻す bin/rails db:migrate:redo バージョンを1つ戻してから1つ上げる bin/rails db:version 現在の適応されているバージョンを表示する dbコマンド
主なdbコマンドも少しまとめてみました
コマンド 意味 bin/rails db:create データベースが作成される bin/rails db:drop データベースの削除される bin/rails db:reset db:dropし、db/schema.rbにもとづいてデータベースを作り直す おしまい
↓こちら参考にしました?
Ruby on Rails 5 速習実践ガイド
Railsガイド
rake or rails コマンドでdbを扱うときのメモ
- 投稿日:2020-03-19T00:31:07+09:00
Ruby on Rails 削除関連まとめ
1. はじめに
アプリの作り始めに、「なんか気に入らないから1回削除して一から作り直したい」と思ったことはありませんか?
私はあります。そんな時に必要になる操作をまとめました。
すでにアプリを作りこんでいる場合は、削除して作り直すわけにもいきませんから変更の方法を探してみてください。自分の環境
- ruby 2.6.5
- Rails 6.0.2
- macOS Catalina 10.15.3
2. アプリの削除
アプリの削除をするにはアプリのフォルダを削除すればいいのですが、その前にデータベースを削除しておきましょう。
同じ名前でアプリを作り直したりしたときに以前のデータベースを利用してしまい、不具合が起きる可能性があります。
アプリケーションフォルダ内で、$ rails db:dropこれでデータベースが削除されます。
そのあとは、以下コマンドでアプリフォルダを削除してもいいですし、ゴミ箱へと放り込んでもいいでしょう。$ cd .. (1つ上のフォルダへ) $ rm -rf [アプリ名]ちなみに上記コマンドの意味は、
- rm = 削除するというコマンド
- -rf = ファイルでなくフォルダを削除するよという -r と「」というメッセージ表示はいらないよという -f の 組み合わせ
- . = 現在のフォルダ
3. コントローラの削除
アプリケーションフォルダ内で以下のコマンドを実行します。
作成の際のrails generate
はrails g
と省略できますが、destroy
は出来ません。
ルーティングは自分でconfig/routes.rb
をいじって消しましょう。$ rails destroy controller [削除したいコントローラ名]4. モデルの削除
マイグレーションを実行する前か後かで操作が変わるので注意。マイグレーション実行というのは、言い換えればデータベースにテーブルを作ること、もしくは
rails db:migrate
を実行することです。わからなかったら実行後の操作をしてみてください。マイグレーション実行前
アプリケーションフォルダ内で以下のコマンドを実行します。
作成の際のrails generate
はrails g
と省略できますが、destroyは出来ません。$ rails destroy model [削除したいモデル名]マイグレーション実行後
まずはマイグレーションまでしてみましょう。以下コマンドを実行。
説明の都合上、2つのモデルを作ってマイグレーションします。(なんの情報も持っていないモデルだけど気にしない。本当はカラム名:データ型
を後ろにつけます)$ rails g model user ← モデル作成 $ rails db:create ← データベース作成(まだデータベースを作っていない場合) $ rails db:migrate ← テーブル作成 $ rails g model post $ rails db:migrate (ここでやるから先の rails db:migrate はやらなくてもいい)モデルを削除する際には、データベースにテーブルが作成されてしまっているのでそちらを削除してからモデルを削除する必要があります。
まずは以下コマンドを実行してみましょう。
$ rails db:migrate:statusマイグレーションを実行した一覧が出てきます。これが
Status Migration ID Migration Name -------------------------------------------------- up 20200318134652 Create users up 20200318134702 Create postsStatusがupになっているということはこのマイグレーションが実行されている(テーブルが
作られている)ということ。以下コマンドのどれかを実行して、削除したいモデルのマイグレーションを取り消しましょう。
$ rails db:rollback (1つだけ前の状態に戻す) $ rails db:rollback STEP=2 (2つ前の状態に戻す) $ rails db rollback VERSION=20200318134652 (Migration ID:20200318134652のマイグレーションまで実行された状態に戻す)マイグレーションが2つくらいなら
rails db:rollback
を2回やればいいですが、たくさん戻したいならステップ数やバージョンを指定すると楽ですね。(不整合が起きるため、過去の特定のマイグレーションだけを取り消すことはできません。)これで実行したマイグレーションが取り消されたので、あとはマイグレーション実行前と同様に
rails destroy [モデル名]
で削除しましょう。マイグレーション取り消しの前にモデルを削除してしまった場合
せっかちで先に
rails destroy [モデル名]
を実行してしまった人のため。
例えば先の例でpostモデルを削除してしまったとします。するとpostのマイグレーションファイルも削除されてしまいrails db:rollbackでマイグレーションを取り消すことすらできなくなります。(絶望)その場合は、まず以下コマンドで新しくマイグレーションファイルを作成します。
$ rails g migration [マイグレーション名]マイグレーション名はなんでもいいですが、わかりやすくdrop_postとでもしておきましょう。
するとdb/migrate/内に以下ファイルが作成されます。
20200318143822_drop_post.rbclass DropPost < ActiveRecord::Migration[6.0] def change end endchangeメソッド内に以下の様に追記しましょう。
20200318143822_drop_post.rbclass DropPost < ActiveRecord::Migration[6.0] def change drop_table :post end endそしてマイグレーションを実行します。するとpostテーブルが削除されているため一件落着。
$ rails db:migrate無駄なマイグレーションファイルが残ってしまうのが自分的に嫌です。ファイルを削除しても問題ないけど
rails db:migrate:status
で表示される履歴の中にはしっかり残っています。(※マイグレーションファイルは削除しない様にしましょう)Status Migration ID Migration Name -------------------------------------------------- up 20200318145751 Create users up 20200318150431 ********** NO FILE ********** up 20200318150544 ********** NO FILE **********5. scaffoldで作成したモデルやコントローラ等の削除
rails g scaffold [モデル名] カラム名:データ型 (カラム名:データ型...)
でモデルやコントローラやルーティングなどを一括作成してくれます。詳しくは別記事を参照してください。rails g scaffoldで作成したんだからもちろん削除は以下コマンド。全部スッキリ削除してくれます。
rails destroy scaffold [モデル名]6. データベース内のデータを削除
モデルやコントローラ、ビューなどを作成し、色々試していているとデータベース内のデータがごちゃってきて初期状態に
戻したい時があると思います。そういうときは以下コマンドを実施。rails db:reset今あるデータベースを削除して新しくもう一度作ってくれます。
db/seeds.rb
を使って初期データ投入を行っている場合は初期データ投入も同時にやってくれるので、自分でrails db:seed
を行うと二重にデータが入ってしまいます。7. さいごに
他にも削除系の操作があれば教えてください。追記させていただきます。
- 投稿日:2020-03-19T00:29:40+09:00
コメント機能の非同期通信
Gemfileの記述
Gemfileにjquery-railsが記載されているか確認し、記載されていない場合は最下部に記載してください。
〜省略〜 # Use jquery as the JavaScript library gem 'jquery-rails' 〜省略〜記述したときはターミナルで
bundle installapplication.jsの記述を確認
application.jsに
//= require jquery
//= require rails-ujs
の記載がされているか確認します。なければ以下のように記述してください。application.js〜省略〜 //= require jquery //= require rails-ujs //= require_tree .必要なクラス名とID
ajaxの非同期通信を実装するために、事前にコメントのフォームにクラス名を与えておきます。
仮に
new_commentというid
textboxというclass
form__submitというclassをつけるとします。
【例】モデル名をTweetとします。app/views/tweets/show.html.erb<%= form_with(model: [@tweet, @comment], local: true, id: "new_comment") do |form| %> <%= form.text_area :text, placeholder: "コメントする" , rows: "2", class: "textbox" %> <%= form.submit "送信", class: "form__submit" %> <% end %>コメント機能を非同期通信化
1.jQueryを記述するためのファイルを作成する
2.フォームが送信されたら、イベントが発火するようにする
3.非同期通信でコメントが保存されるようにする
4.respond_toを使用してHTMLとJSONの場合で処理を分ける
5.jbuilderを使用して、作成したメッセージをJSON形式で返す
6.返ってきたJSONをdoneメソッドで受取り、HTMLを作成する
7.エラー時の処理を行う
を作業していきます。jQueryを記述するためのファイルを作成
JavaScriptファイルをassets/javascripts以下に作成します。今回はコメント機能の作成なのでcomment.jsのファイルを作ります。
フォームが送信されたら、イベントが発火
submitボタンを押した時に、イベントが発火するようにします。
comment.jsに、コメントフォームが送信された時フォームに入力された値を受け取れるようにします。
【例】comment.js$(function(){ $('#new_comment').on('submit', function(e){ e.preventDefault(); var formData = new FormData(this); }) })フォームが送信された時、というイベントを設定したい場合は、form要素を取得してonメソッドを使います。
今回のアプリの画面ではform要素のid属性が#new_commentにしています。フォームの送信についてonメソッドでイベントをセッティングする際は、form要素自体に設定するようにします。
最初から設定されているフォームの動作はキャンセルします。
フォームが送信される時、何も設定していない状態(デフォルトの状態)だとフォームを送信するための通信が行われるため、preventDefault()を使用してデフォルトのイベントを止めます。FormData
フォームのデータの送信に使用することができます。その他にも、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。今回はコメントフォームがあるので、そのフォームの情報を取得するのに使います。
new FormData(フォーム要素)とすることでFormDataを作成できます。
今回FormDataオブジェクトの引数はthisとなっていますが、イベントで設定したfunction内でthisを利用した場合は、イベントが発生したノード要素を指します。今回の場合は、new_commentというIDがついたフォームの情報を取得しています。フォームの値を確認
comment.js$(function(){ $('#new_comment').on('submit', function(e){ e.preventDefault(); console.log(this) #追加部分 var formData = new FormData(this); }) })検証の画面でコンソールを開き、thisの中身がフォームに入力した値が出力されていればOKです。
JavaScriptではconsole.logを用いてデバッグを行います。非同期通信でコメントを保存
フォームに入力されたデータを取得したら、必要なAjax関数のオプションを揃えて非同期通信を行います。
1.フォームの送信が行われた時に、Ajaxによる非同期通信でcreateアクションを動かす
2.createアクション内でコメントを保存し、respond_toを使用してHTMLとJSONの場合で処理を分ける
console.log(this)は削除します。comment.js$(function(){ $('#new_comment').on('submit', function(e){ e.preventDefault(); var formData = new FormData(this); #追加〜 var url = $(this).attr('action') $.ajax({ url: url, type: "POST", data: formData, dataType: 'json', processData: false, contentType: false #〜追加 }) }) })フォームの送信先のurlを定義しています。$(this)は、thisで取得できる要素をjQueryオブジェクト化しています。
attrメソッド
要素が持つ指定属性の値を返します。
要素が指定属性を持っていない場合、関数はundefinedを返します。
今回はイベントが発生した要素のaction属性の値を取得しており、今回のaction属性にはフォームの送信先のurlの値が入っています。
これでリクエストを送信する先のURLを定義することができました。processDataオプション
デフォルトではtrueになっており、dataに指定したオブジェクトをクエリ文字列(例: msg.txt?b1=%E3%81%8B&b2=%E3%81%8D )に変換する役割があります。
クエリ文字列とは、WebブラウザなどがWebサーバに送信するデータをURLの末尾に特定の形式で表記したものです。contentTypeオプション
サーバにデータのファイル形式を伝えるヘッダです。こちらはデフォルトでは「text/xml」でコンテンツタイプをXMLとして返してきます。
ajaxのリクエストがFormDataのときはどちらの値も適切な状態で送ることが可能なため、falseにすることで設定が上書きされることを防ぎます。FormDataをつかってフォームの情報を取得した時には必ずfalseにするという認識です。
他にもAjaxリクエストを送信するオプションの参考です。
(http://js.studio-kingdom.com/jquery/ajax/ajax)コメントを保存し、respond_toを使用してHTMLとJSONの場合で処理を分ける
非同期通信によって、comment#createを動かすことに成功し、正しくAjaxからdataを送れていれば、そのまま保存することが可能です。
保存ができていることを確認したら、respond_toを使用してHTMLとJSONの場合で処理を書いていきます。
【例】上のcomments_controller.rbが同期通信です。それを非同期通信の記述に編集します。comments_controller.rbclass CommentsController < ApplicationController def create Comment.create(comment_params) end private def comment_params params.require(:comment).permit(:text).merge(user_id: current_user.id, tweet_id: params[:tweet_id]) end endcomments_controller.rbdef create @comment = Comment.create(comment_params) #編集〜 respond_to do |format| format.html { redirect_to tweet_path(params[:tweet_id]) } format.json end #〜編集 end private def comment_params params.require(:comment).permit(:text).merge(user_id: current_user.id, tweet_id: params[:tweet_id]) endローカル変数commentは、スコープの関係でこの後のjbuilder側で使用できないので、インスタンス変数@commentに編集します。
respond_to doを使用し、リクエストされたformatによって処理を分けます。フォーマットがjsonの時は、format.jsonに引数としてインスタンスを渡します。今回はjbuilderを使ってJavaScriptに返すデータを作成します。jbuilder
rails newコマンドでアプリケーションを作成した際にgemfileにデフォルトで記述されているgemで、入力データをJSON形式で出力するテンプレートエンジンです。
Jbuilderを利用するときは、コントローラ内でrender json: ○○を行いません。jbuilderを使用して、作成したメッセージをJSON形式で返す
respond_toで処理を分けたら、jbuilderを使用してJavaScriptファイルに返すデータを作成します。
jbuilderは、viewと同じように該当するアクションと同じ名前にします。
commentのcreateアクションに対応するjbuilderのファイルになるので、作成するのはviews/comments/create.json.jbuilderになります。
【例】今回はコメント欄にtextとuser.idとuser.nicknameがあるとします。views/comments/create.json.jbuilderjson.text @comment.text json.user_id @comment.user.id json.user_name @comment.user.nicknamejbuilderファイルでは基本的にjson.KEY VALUEという形で書くことができます。
こうすることによってJavaScriptファイルに返ってきたデータをjbuilderで定義したキーとバリューの形で呼び出して使うことができます。返ってきたJSONをdoneメソッドで受取り、HTMLを作成する
非同期通信の結果として返ってくるデータは、done(function(data) { 処理 })の関数の引数で受け取ります。
comment.js$(function(){ function buildHTML(comment){ #追加〜 var html = `<p> <strong> <a href=/users/${comment.user_id}>${comment.user_name}</a> : </strong> ${comment.text} </p>` return html; } #〜追加 $('#new_comment').on('submit', function(e){ e.preventDefault(); var formData = new FormData(this); var url = $(this).attr('action'); $.ajax({ url: url, type: "POST", data: formData, dataType: 'json', processData: false, contentType: false }) .done(function(data){ #追加〜 var html = buildHTML(data); $('.comments').append(html); $('.textbox').val(''); $('.form__submit').prop('disabled', false); }) #〜追加 }) });.done〜は、非同期通信に成功した時の記述です。function(data)となっていますが、非同期通信に成功した時の即時関数の第一引数には、サーバから返されたデータが入っています。この場合のサーバから返ってくるデータというのは、jbuilderで作成したcreate.json.jbuilderのデータです。
$('.form__submit').prop('disabled', false);は、 htmlの仕様でsubmitボタンを一度押したらdisabled属性というボタンが押せなく属性が追加されます。
そのため、disabled属性をfalseにする記述を追加しています。
function buildHTML(comment){〜はHTMLを追加しています。テンプレートリテラル記法
ダブルクオートやシングルクオートの代わりにバックティック文字(`)で囲むことで、複数行文字列や文字列内挿入機能を使用できます。
buildHTMLの引数として渡されたcommentはサーバから返されたデータであるjbuilderのデータであるため、ファイル内で定義したキーとバリューの形式で使用できます。エラー時の処理を行う
comment.js〜省略〜 .done(function(data){ var html = buildHTML(data); $('.comments').append(html); $('.textbox').val(''); $('.form__submit').prop('disabled', false); }) .fail(function(){ #追加〜 alert('error'); }) #〜追加 〜省略〜失敗した場合の処理で、アラートを表示します。