- 投稿日:2020-01-25T23:17:08+09:00
【Rails】Qiita 週間いいね数ランキング【タグ別】
他のタグ
集計期間
01月18日 ~ 01月25日
いいね数ランキング
1位: WEBエンジニアへの転職を目指す外資系新卒が、8週間の学習過程を晒してみる
JavaScript
Rails
転職
React
未経験エンジニア
12いいね
@Ryo__Mさん(01月20日 07時55分の投稿)2位: Rails 6ではsend_data/send_fileメソッド呼び出し時にERB::Util.url_encodeは不要です
Ruby
Rails
9いいね
@jnchitoさん(01月20日 23時32分の投稿)3位: devise ユーザーのプロフィール画面作成と編集(デフォルトをカスタマイズ)
Ruby
Rails
devise
Gem
初心者
5いいね
@akr03xxxさん(01月20日 14時01分の投稿)4位: 【翻訳】URI.escapeは非推奨メソッドです。あなたのクエリ文字列をパーセントエンコードするには
Ruby
Rails
3いいね
@jnchitoさん(01月25日 03時32分の投稿)5位: Rails Javascript/Html: 投稿編集画面で写真の表示を確認したい!
JavaScript
Rails
HTML5
2いいね
@kokeshi1357さん(01月24日 11時45分の投稿)6位: Railsで作成した1対1のメッセージ機能をコードリーディング
Rails
アソシエーション
2いいね
@3rudenさん(01月22日 05時47分の投稿)7位: 【Rails×Ajax】いいね機能の実装で上手く出来ないあなたへの2つの注意喚起 #学習者向け
Ruby
JavaScript
Rails
エラー対処
2いいね
@shoji621さん(01月20日 03時03分の投稿)8位: configure IIS with ruby on rails app on windows server
Ruby
Rails
Windows
deploy
Deployment
2いいね
@alokrawat050さん(01月19日 12時51分の投稿)9位: ページ遷移先でリロードしないと非同期通信(ajax)できない
Ruby
JavaScript
Rails
2いいね
@avicii2314さん(01月19日 05時18分の投稿)10位: https(SSL)通信の環境下でjavascriptが動かなくなる場合の原因と解決方法 ( 本番環境(AWS)でjavascriptを読み込む方法 )
Ruby
JavaScript
Rails
2いいね
@avicii2314さん(01月19日 04時17分の投稿)11位: 【jQuery】RailsでValidation Pluginを使った動的なバリデーションチェックの実装 〜詳細実装/Bootstrap編〜
Ruby
Rails
jQuery
Bootstrap
Validation
1いいね
@tiphp452さん(01月25日 01時24分の投稿)12位: Railsアプリ起動時に突然「Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)」になった時の対処法
Rails
MySQL
1いいね
@President_Takaさん(01月25日 01時04分の投稿)13位: Railsの思想
Rails
1いいね
@china55さん(01月24日 11時26分の投稿)14位: メモ:ActionMailerのログにメールアドレスが出ないようにする
Rails
ActionMailer
1いいね
@shouta-devさん(01月24日 04時50分の投稿)15位: Rspecと Factoryの使い方
Ruby
Rails
RSpec
FactoryGirl
1いいね
@gototakumaさん(01月23日 14時47分の投稿)16位: 【Rails】 Heroku, Aws で詰まったときに見る記事まとめ
Rails
Heroku
AWS
1いいね
@wafuwafu13さん(01月23日 03時07分の投稿)17位: rakeタスクに引数を渡したいとき
Ruby
Rails
rake
1いいね
@kaobabaさん(01月23日 02時10分の投稿)18位: [Ruby on Rails]データベースの作成、カラムの追加
Ruby
Rails
1いいね
@sansiroさん(01月22日 10時19分の投稿)19位: 自動デプロイ(Capistrano)でエラー mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません
Ruby
Rails
Capistrano
AWS
Rails5
1いいね
@nousiさん(01月21日 15時21分の投稿)20位: CodeCommit + CodeDeploy + CodePipelineでEC2にデプロイ~CodeDeployの設定~
Rails
AWS
CodeDeploy
CodeCommit
CodePipeline
1いいね
@k_senbeiさん(01月21日 11時19分の投稿)21位:
create_or_find_by
はユニーク制約が定義されたテーブルで効いてくる
Rails
Rails6
1いいね
@ryosuke_satoさん(01月21日 10時00分の投稿)22位: 【Rails】enumを使用したセレクトボックスの実装とDBへの保存
Ruby
Rails
1いいね
@y-sunaさん(01月21日 08時11分の投稿)23位: Rails 6+Grapeで作るAPIサーバーにDeviseトークン認証を付ける
Ruby
Rails
devise
grape
devise_token_auth
1いいね
@shimizu-nowhereさん(01月21日 07時50分の投稿)24位: 【Rails】ActiveRecordで関連テーブルのカラムでwhereまたは、orderする【ActiveRecord】
Rails
ActiveRecord
1いいね
@yutaroadachiさん(01月21日 06時12分の投稿)25位: Cloud9でRails 6.0のSeleniumとGoogle Chromeを使える設定しましょう!
Rails
Chrome
Selenium
cloud9
Rails6
1いいね
@pineappledreamsさん(01月21日 02時33分の投稿)26位: Rails6 アプリからメールを送信する デプロイ環境編
Rails
Mac
初心者
初心者向け
Rails6
1いいね
@miriwoさん(01月20日 16時53分の投稿)27位: 【Rails】Strong Parametersの書き方について
Rails
1いいね
@ktganaoさん(01月20日 13時48分の投稿)28位: railsにおける get と post の違い
Rails
1いいね
@sakana_fishさん(01月20日 12時21分の投稿)29位: エンジニアのポートフォリオを作ってみた
CSS
JavaScript
Rails
HTML5
jQuery
1いいね
@ssstttさん(01月19日 13時06分の投稿)30位: high_voltageで利用規約等の静的ページを作る
Ruby
Rails
静的ページ
初学者向け
high_voltage
1いいね
@royroyさん(01月19日 08時46分の投稿)31位: RailsにおけるAjaxの実装(JavaScriptとjQueryのコード比較)
Ruby
JavaScript
Rails
jQuery
Ajax
1いいね
@t-yama-3さん(01月19日 08時19分の投稿)32位: Hamlでのlink toの書き方【Rails】
Rails
haml
1いいね
@Pirori3182さん(01月19日 06時26分の投稿)33位: 【Rails】ActionMailer + AWS SES
Ruby
Rails
AWS
ses
ActionMailer
1いいね
@syukan3さん(01月19日 05時50分の投稿)34位: Railsチュートリアル 第13章 ユーザーのマイクロポスト - 本番環境での画像アップロード
Rails
Heroku
AWS
初心者
Railsチュートリアル
1いいね
@rapidliner00さん(01月19日 05時49分の投稿)
- 投稿日:2020-01-25T23:17:08+09:00
【Rails】Qiita 週間いいね数ランキング【自動更新】
他のタグ
集計期間
01月19日 ~ 01月26日
いいね数ランキング
1位: 【翻訳】URI.escapeは非推奨メソッドです。あなたのクエリ文字列をパーセントエンコードするには
Ruby
Rails
17いいね
@jnchitoさん(01月25日 12時32分の投稿)2位: WEBエンジニアへの転職を目指す外資系新卒が、8週間の学習過程を晒してみる
JavaScript
Rails
転職
React
未経験エンジニア
12いいね
@Ryo__Mさん(01月20日 16時55分の投稿)3位: Rails 6ではsend_data/send_fileメソッド呼び出し時にERB::Util.url_encodeは不要です
Ruby
Rails
9いいね
@jnchitoさん(01月21日 08時32分の投稿)4位: devise ユーザーのプロフィール画面作成と編集(デフォルトをカスタマイズ)
Ruby
Rails
devise
Gem
初心者
6いいね
@akr03xxxさん(01月20日 23時01分の投稿)5位: 【jQuery】RailsでValidation Pluginを使った動的なバリデーションチェックの実装 〜詳細実装/Bootstrap編〜
Ruby
Rails
jQuery
Bootstrap
Validation
2いいね
@tiphp452さん(01月25日 10時24分の投稿)6位: Rails Javascript/Html: 投稿編集画面で写真の表示を確認したい!
JavaScript
Rails
HTML5
2いいね
@kokeshi1357さん(01月24日 20時45分の投稿)7位: Railsで作成した1対1のメッセージ機能をコードリーディング
Rails
アソシエーション
2いいね
@3rudenさん(01月22日 14時47分の投稿)8位: 【Rails×Ajax】いいね機能の実装で上手く出来ないあなたへの2つの注意喚起 #学習者向け
Ruby
JavaScript
Rails
エラー対処
2いいね
@shoji621さん(01月20日 12時03分の投稿)9位: 【Rails】Qiita 週間いいね数ランキング【自動更新】
Rails
1いいね
@kou_pg_0131さん(01月25日 23時17分の投稿)10位: Railsアプリ起動時に突然「Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)」になった時の対処法
Rails
MySQL
1いいね
@President_Takaさん(01月25日 10時04分の投稿)11位: Railsの思想
Rails
1いいね
@china55さん(01月24日 20時26分の投稿)12位: メモ:ActionMailerのログにメールアドレスが出ないようにする
Rails
ActionMailer
1いいね
@shouta-devさん(01月24日 13時50分の投稿)13位: Rspecと Factoryの使い方
Ruby
Rails
RSpec
FactoryGirl
1いいね
@gototakumaさん(01月23日 23時47分の投稿)14位: 【Ruby】mapメソッドのつかいかた(+別メソッドとの組み合わせの例など)
Ruby
Rails
1いいね
@4EAE_Learnerさん(01月23日 20時11分の投稿)15位: 【Rails】 Heroku, Aws で詰まったときに見る記事まとめ
Rails
Heroku
AWS
1いいね
@wafuwafu13さん(01月23日 12時07分の投稿)16位: rakeタスクに引数を渡したいとき
Ruby
Rails
rake
1いいね
@kaobabaさん(01月23日 11時10分の投稿)17位: [Ruby on Rails]データベースの作成、カラムの追加
Ruby
Rails
1いいね
@sansiroさん(01月22日 19時19分の投稿)18位: 自動デプロイ(Capistrano)でエラー mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません
Ruby
Rails
Capistrano
AWS
Rails5
1いいね
@nousiさん(01月22日 00時21分の投稿)19位: CodeCommit + CodeDeploy + CodePipelineでEC2にデプロイ~CodeDeployの設定~
Rails
AWS
CodeDeploy
CodeCommit
CodePipeline
1いいね
@k_senbeiさん(01月21日 20時19分の投稿)20位:
create_or_find_by
はユニーク制約が定義されたテーブルで効いてくる
Rails
Rails6
1いいね
@ryosuke_satoさん(01月21日 19時00分の投稿)21位: 【Rails】enumを使用したセレクトボックスの実装とDBへの保存
Ruby
Rails
1いいね
@y-sunaさん(01月21日 17時11分の投稿)22位: Rails 6+Grapeで作るAPIサーバーにDeviseトークン認証を付ける
Ruby
Rails
devise
grape
devise_token_auth
1いいね
@shimizu-nowhereさん(01月21日 16時50分の投稿)23位: 【Rails】ActiveRecordで関連テーブルのカラムでwhereまたは、orderする【ActiveRecord】
Rails
ActiveRecord
1いいね
@yutaroadachiさん(01月21日 15時12分の投稿)24位: Cloud9でRails 6.0のSeleniumとGoogle Chromeを使える設定しましょう!
Rails
Chrome
Selenium
cloud9
Rails6
1いいね
@pineappledreamsさん(01月21日 11時33分の投稿)25位: Rails6 アプリからメールを送信する デプロイ環境編
Rails
Mac
初心者
初心者向け
Rails6
1いいね
@miriwoさん(01月21日 01時53分の投稿)26位: 【Rails】Strong Parametersの書き方について
Rails
1いいね
@ktganaoさん(01月20日 22時48分の投稿)27位: railsにおける get と post の違い
Rails
1いいね
@sakana_fishさん(01月20日 21時21分の投稿)
- 投稿日:2020-01-25T21:12:33+09:00
【gon】jsでRails変数を取得する
Railsでjsライブラリを使うときに楽にRailsで定義した変数をJavaScriptに渡したい!楽したい!
プログラマ三大美徳
1.怠慢(Laziness)
2.短気(Impatience)
3.傲慢(Hubris)まさにこれですね。
何を使うか?
RailsといえばGemですね。[gon]というgemです。
https://github.com/gazay/gonインストール
Gemfileに記載
Gemfilegem 'gon'ターミナルからインストール
ターミナルbundle install読み込み設定
application.html.erb<%= include_gon %> <%= javascript_include_tag "application" %>使ってみる
****.controller.rbgon.user_name = 'my name is imaizumi'****.jsconsole.log(gon.user_name)バッチリ変数を渡せました
- 投稿日:2020-01-25T20:31:17+09:00
Rails new とは
- 投稿日:2020-01-25T18:12:25+09:00
Docker-composeでbundle installしてるのにgemの内容反映されないんですけど
注意事項
完全に個人用メモです。公式情報でもなんでもありません。ググってこの記事に来てしまった方はお気をつけください。違っていたら即直しますのでガンガンご指摘ください。(個人用メモなので追加もしていきます)
そもそもbundle installしたらサーバー再起動しろや
なので、gemfile編集してbundle installしたら以下のコマンド打てば良い(環境によるけど)
docker-compose restart
・・・コンテナ再起動そしたらGemの内容が反映されます。
docker勉強不足だって、はっきりわかんだね。
イメージをビルドしなおしたりコンテナ削除したりしなくて良い
dockerを理解してないと以下のようなコマンドを打ち始めます
docker-compose build
・・・イメージビルド
docker-compose up -d
・・・コンテナ作成&起動結果、コンテナが増えまくるわけです。(えぇ。。。)
コンテナやたら多いと思ったら原因これかよw(錯乱)
まあこの方法でも解決できるんですけどね。。
- 投稿日:2020-01-25T17:32:16+09:00
ActiveRecord::StatementInvalid: Mysql2::Error: Duplicate column name '_id': ALTER TABLE `` ADD `_id` bigint
カラムの追加の後にrails db:migrate
をした際にタイトルのエラーがMysqlにて出て苦戦したので、同じような方がいるかもなのでメモとして残します。
まず最初に結論からです。エラーの原因は、migrateした際
rails db:migrate:status
up 20200123145035 Create users
up 20200123150804 Create
up 20200124043414 Create
down 20200125060439 Create
down 20200125064510 Create*downと書かれているファイルならupされてないので問題ないと作り直す為に、削除して作り直した事が原因で
起こりました。downのままですが、追加しようとしたカラムが一部だけ追加されていた事による重複です。初心者さんで同じような事になる方もいると思いますので、その際しっかりとロールバックまたは、データベースを削除したかのご確認をしてみてください。
直し方
そして直した方法ですが・・・
rails db:drop
をしてデータベースを再作成する事でup済みのものに追加してしまいマイグレーションファイルが削除されなくなってしまったものをなかった事にしました。rails db:create
raild db:migrate
これで、 rails g AddxxxRefToテーブル名 カラム名: で追加し直し。
正常に戻りました。今回は、作りたてだったので問題なかったですが、デプロイ済みの場合などはユーザーデータが消えたりして大変な事になりますので、お気をつけください。
- 投稿日:2020-01-25T16:56:13+09:00
Docker + rails + mysqlで開発環境を構築
はじめに
今回は、railsの開発環境をDocker+rails+mysqlで用意します。
構成
構成はローカルのMacにDockerを立て、webとdbコンテナをdocker-composeで管理します。
開発環境
Docker 19.03.5
Ruby 2.6.5
Rails 5.2.4
MySQL 5.7.29前提条件
Macを利用
Docker Desktopをインストール
まずは、ローカルのMacにDocker Desktopをインストールします。
https://www.docker.com/get-started
「Download Desktop and Take a Tutorial」のボタンをクリックすると画面が遷移し、
アカウントがある人はログイン、ない人は「Sign Up」を押してアカウントを作成します。アカウント作成後、ログインし 「Get started with Docker Desktop」を押すと画面が遷移するので「Download Docker Desktop for Mac」を押しダウンロードします。
ダウンロード完了後、インストールします。
install後、Macのターミナルにてdocker versionと打ち、バージョンが出れば無事インストールは完了です。$ docker version Client: Docker Engine - Community Version: 19.03.5 API version: 1.40 Go version: go1.12.12 Git commit: 633a0ea Built: Wed Nov 13 07:22:34 2019 OS/Arch: darwin/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.5 API version: 1.40 (minimum version 1.12) Go version: go1.12.12 Git commit: 633a0ea Built: Wed Nov 13 07:29:19 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.2.10 GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339 runc: Version: 1.0.0-rc8+dev GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 docker-init: Version: 0.18.0 GitCommit: fec3683web(rails)コンテナの構築
開発を行うために任意の作業ディレクトリを作成します。
$ mkdir task_app/ $ cd task_appGemfileの準備
オプションでディレクトリのマウントを指定していることで、Docker環境で作成されたGemfileがローカル環境に作成されます。
$ docker run --rm -v `pwd`:/task_app -w /task_app ruby:2.6 bundle init Unable to find image 'ruby:2.6' locally 2.6: Pulling from library/ruby 8f0fdd3eaac0: Pull complete d918eaefd9de: Pull complete 43bf3e3107f5: Pull complete 27622921edb2: Pull complete dcfa0aa1ae2c: Pull complete 0e1f1dc37f65: Pull complete c76a82442849: Pull complete 5161fd3df3c4: Pull complete Digest: sha256:f38fce2b70ba23e90d6397995bea8419b86dd3f20b73846681adb52c63c0b002 Status: Downloaded newer image for ruby:2.6 Writing new Gemfile to /task_app/GemfileGemfileがローカルに作成されますので、railsのバージョンを指定します。
利用したいバージョンに合わせて適宜修正してください。$ vi Gemfile # gem "rails" gem 'rails', '~> 5.2.3'Dockerイメージの作成
rails環境のDockerイメージを作成します。
Dockerfileの作成 → ビルド → Dockerイメージ(task_app)
※Dockerfileはないので新規作成します。
$ vi Dockerfile FROM ruby:2.6 WORKDIR /task_app COPY Gemfile /task_app/Gemfile RUN bundle install $ docker build -t task_app . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM ruby:2.6 ---> a161c3e3dda8 Step 2/4 : WORKDIR /task_app ---> Running in a6b5dec7f0ed Removing intermediate container a6b5dec7f0ed ---> 16367607e3e5 Step 3/4 : COPY Gemfile /task_app/Gemfile ---> 99de34366eef Step 4/4 : RUN bundle install ---> Running in 8839dbf87256 Fetching gem metadata from https://rubygems.org/............. Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Fetching rake 13.0.1 Fetching rails 5.2.4.1 Installing rails 5.2.4.1 Bundle complete! 1 Gemfile dependency, 41 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. Post-install message from i18n: HEADS UP! i18n 1.1 changed fallbacks to exclude default locale. But that may break your application. If you are upgrading your Rails application from an older version of Rails: Please check your Rails app for 'config.i18n.fallbacks = true'. If you're using I18n (>= 1.1.0) and Rails (< 5.2.2), this should be 'config.i18n.fallbacks = [I18n.default_locale]'. If not, fallbacks will be broken in your app by I18n 1.1.x. If you are starting a NEW Rails application, you can ignore this notice. For more info see: https://github.com/svenfuchs/i18n/releases/tag/v1.1.0 Removing intermediate container 8839dbf87256 ---> 89e179509cba Successfully built 89e179509cba Successfully tagged task_app:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE task_app latest 89e179509cba About a minute ago 926MB作成されてますね。
Railsアプリの作成
作成したDockerイメージ(task_app)を利用してrails newを実行し、Railsアプリを作成します。
$ docker run --rm -v `pwd`:/task_app task_app rails new . -B --database=mysql exist create README.md create Rakefile create .ruby-version create config.ru create .gitignore conflict Gemfile Overwrite /task_app/Gemfile? (enter "h" for help) [Ynaqdhm] force Gemfile run git init from "." Initialized empty Git repository in /task_app/.git/ create package.json create app create app/assets/config/manifest.js create app/assets/javascripts/application.js create app/assets/javascripts/cable.js create app/assets/stylesheets/application.css create app/channels/application_cable/channel.rb create tmp/storage create tmp/storage/.keep remove config/initializers/cors.rb remove config/initializers/new_framework_defaults_5_2.rbRailsからデータベースへ接続するためのdatabase.ymlファイルが作成されますので修正します。
$ vi config/database.yml default: &default adapter: mysql2 encoding: utf8 pool: username: root password: xxxxxxx #追加: MysqlのMYSQL_ROOT_PASSWORDと同じ値 host: db #追加: MySQLのコンテナ名と同じ値。この後構築します。docker-compose.ymlにwebコンテナを追加します。
Railsが起動するDockerイメージを作成します。
$ vi Dockerfile FROM ruby:2.6 RUN apt-get update -qq && apt-get install -y nodejs #追加 WORKDIR /task_app COPY Gemfile /task_app/Gemfile RUN bundle install CMD ["rails", "server", "-b", "0.0.0.0"] #追加RailsアプリはDocker Composeを利用して起動させます。
docker-compose.ymlを作成し、webコンテナの起動設定をdocker-compose.ymlに記載します。# vi docker-compose.yml version: '3' services: web: build: . ports: - '3000:3000' volumes: - .:/task_appコンテナを停止するとmysqlのデータが消えてしまうため、データ永続化のため、volumesを入れています。
Dockerfileを編集したのでdocker-composeコマンドでDockerイメージをビルドします。
$ docker-compose build Building web Step 1/6 : FROM ruby:2.6 ---> a161c3e3dda8 Step 2/6 : RUN apt-get update -qq && apt-get install -y nodejs ---> Running in c287be3cb98f Reading package lists... Building dependency tree... Reading state information... The following additional packages will be installed: libc-ares2 libnode64 libuv1 nodejs-doc Suggested packages: npm The following NEW packages will be installed: libc-ares2 libnode64 libuv1 nodejs nodejs-doc 0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded. Need to get 6753 kB of archives. After this operation, 30.4 MB of additional disk space will be used. * For more details, please refer to the Sass blog: https://sass-lang.com/blog/posts/7828841 Removing intermediate container 711351e6bba5 ---> 5486636e708a Step 6/6 : CMD ["rails", "server", "-b", "0.0.0.0"] ---> Running in 82d851651892 Removing intermediate container 82d851651892 ---> a895f6cec871 Successfully built a895f6cec871 Successfully tagged task_app_web:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE task_app_web latest a895f6cec871 8 minutes ago 1.02GB task_app latest 89e179509cba About an hour ago 926MBここまででweb(rails)コンテナの構築が完了です。
db(mysql)コンテナの構築
depends_onにdbコンテナを追加します。
※depends_onはwebとDBコンテナの作成順序と依存関係を定義します。# vi docker-compose.yml version: '3' services: web: build: . ports: - '3000:3000' volumes: - .:/task_app depends_on: #追加 - db #追加 db: #追加 image: mysql:5.7 #追加 volumes: #追加 - ./mysql:/var/lib/mysql #追加 environment: #追加 MYSQL_ROOT_PASSWORD: 'xxxxx' #追加: Railsのpasswordと同じ値一旦、Dockerコンテナを起動します。
$ docker-compose upただし、dbコンテナはありますがRuby on Railsで利用するデータベースがないので作成します。
$ docker-compose exec web rake db:create Created database 'task_app_development' Created database 'task_app_test' $ docker-compose exec db mysql -uroot -pxxxxx mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.7.29 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +----------------------+ | Database | +----------------------+ | information_schema | | mysql | | performance_schema | | sys | | task_app_development | ← 作成 | task_app_test | +----------------------+ 6 rows in set (0.00 sec) mysql>データベースも作成できましたので、db(mysql)コンテナの準備も完了です。
ブラウザでアクセス
http://localhost:3000/ でアクセスして確認します。
見慣れた画面が出ましたね!
まとめ
Docker環境で簡単にrailsの開発環境が用意できました!
ちなみにDockerのキャラクターは、Moby(モビー)って言うらしいです。
- 投稿日:2020-01-25T15:36:38+09:00
メタプログラミング Ruby memo #1
概要
現在Rubyを勉強しており、「Rubyを勉強するならメタプログラミングRubyは必読!」という先輩からの教えがあり、読んでいるのでそれのまとめメモです。
筆者のRubyに関してのスキルは「プロになるためのRuby」を読んでRailsチュートリアルをさらっとくらいのレベルです。
お見知り置きいただければと。。。今回はまずメタプログラミングに関してまとめようと思います。
個人的レベル感
「上級者向け過ぎてわからないことも多いだろうなあ」とびびっていたのですが案外わかりやすく、ひとつひとつコードを書きながら進めていくと理解が進むような造りになっていると感じました。
翻訳書なので、表現の仕方が基本的に海外よりなので、そこに関して苦手な人は読みづらいかもです...
何かあるごとに開く本というのが誰しもあると思うのですが、個人的にはこの本はそこにランクインするレベルだと思います。
そもそもメタプログラミングって何?(広い意味での)
- ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと( wikipedia)
- 他のプログラム ( あるいは自身 ) を操作したり出力するプログラムを書くこと、または作業の一部をコンパイル時に行い、残りの作業を実行時に行うようなプログラムを書くことである。
- コードジェネレータやコンパイラが行うコード生成のこと。
Rubyは「動的メタプログラミング」
- Rubyに関して言えば、「コードを生成するためのコードを書くこと」が簡単にできてしまう。 (本書の言葉を借りれば「シームレスかつエレガントに」)
- 「魔法」や「黒魔術」と呼ばれるくらい、簡潔にコードが書ける。
- 「大いなる力には、大いなる責任が伴うことを忘れてはいけない」 by Matz
言語要素を実行時に操作するコードを記述すること
コードジェネレータやコンパイラが行うコード生成のことも、「広い意味でのメタプログラミング」と言えるのだが、Rubyはこの定義には含まれない。
これを「静的メタプログラミング」と呼ぶならば、Rubyは「動的メタプログラミング」と呼べるメタプログラミングに利用されている技術の例
実際に本書で使われている技術の一例を紹介しようと思います。
※ もっと沢山あります。既存のクラスの振る舞いを変更する(モンキーパッチ)
mokey_patch.rb"abc".reverse # => "cba" class String def reverse "オーバーライド" end end "abc".reverse # => "オーバーライド"1. 再定義したメソッドから以前のメソッドをエイリアスで呼び出す
around_arias.rb# String#reverseに新たな機能を追加する "abc".reverse # => "cba" class String alias_method :old_reverse, :reverse def reverse "hoge#{old_reverse}hoge" end end "abc".reverse # => "hogecbahoge"2. 該当するメソッドのないメッセージに応答する
method_missing.rbclass Hoge; end hoge = Hoge.new hoge.no_define_method # => NoMethodError (undefined method `no_define_method' for #<Hoge:0x00007f9649836be8>) # BasicObject#method_missingを書き換える(noMethodErrorを返しているメソッド) class Hoge def method_missing(name, *args) name.to_s.reverse end end hogehoge = Hoge.new hogehoge.no_define_method # => "hogedohtem_enifed_onhoge"動的メソッド
dynamic_method.rbclass C; end C.class_eval do define_method :my_method do "動的メソッド" end end obj = C.new obj.my_method # => "動的メソッド"ざっくりまとめると
- 上記のようなRubyの技術を駆使してコードのリファクタなどを例を用いてわかりやすく説明してくれています。
- ActiveRecordなどのRailsのコードもどのようなスキルを駆使して書かれているか説明してくれているので、難しいコードを読んだことない人にとってはとっつきやすいかもしれません。
- 本書の最後のほうでも言っているのですが、メタプログラミングがどうとか考えずにただのプログラミングだと思えという言葉がなぜかしっくりきました。 (自分のバイアスがかかっていただけかも?)
- Rubyの「特徴」を事細かに説明してくれている良書だと思います。
- 投稿日:2020-01-25T14:55:51+09:00
【Rails】Railsとdeviseのデフォルトバリデーションを解除する方法
はじめに
知人がemailの正規表現を使ったバリデーションを自ら作成して設定しようとした際、うまく設定を反映させられませんでした
いろいろ調べたところRailsのバリデーションやらdeviseのバリデーションやらが絡んでいたためでした
今まで知らないで使ってたことなど勉強になったことが多かったので整理してまとめておきます対象読者
- form_withやform_forが何かをなんとなく理解している人
- バリデーションが何かをなんとなく理解してる人
環境
- Ruby: 2.5.1
- Rails: 5.2.3
状況
- 正規表現で~@~.~という形じゃないとアドレスとして登録できないようなカスタムバリデーションを作成した
- そのバリデーションを有効にしたが、下記の画像のような謎のバリデーションにひっかかった
自分で作ったカスタムバリデーションじゃないのがでてきた。。。ってなったんですが
結論、Railsのバリデーションとdeviseのバリデーションを解除してやれば、目的通り自作のカスタムバリデーションのみ反映させられました以下に、やり方と解説を記載します
Railsのバリデーション設定
Railsでメールアドレスやパスワードをユーザーに入力させるとき、入力フォームを作成するためにform_forやform_withを使いますよね。こんな感じで
new.html.haml= form_with(model: @user, local: true, class: 'hoge') do |form| = form.label :email, 'メールアドレス' = form.email_field :emailここで記載したemail_fieldがさっきのバリデーションの正体です
このように記載することでRailsはこの入力フォームをemailだと認識して、簡単なバリデーションを自動でかけるようになっているみたいですなので先ほどの記載を以下のように書き換えるとRails側でバリデーションをかけないようにできます
new.html.haml#変更前 = form.email_field :email #変更後 = form.text_field :email先ほどのバリデーションは消えましたが、フラッシュメッセージにバリデーションが2つ出てきてしまいました
deviseのバリデーション設定
今のままだとバリデーションが2つ出てきてしまいます。先ほどの画像の左側がdeviseのバリデーション、右側が自分で設定したカスタムバリデーションです
今回は自分が設定したカスタムバリデーションだけ表示させたいので、deviseのバリデーション設定を解除します通常、deviseをインストールした場合、モデル内に下記のような記述があると思います
models/user.rbdevise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatableこの:validatableがdeviseのバリデーションなので、この記述を消します
models/user.rbdevise :database_authenticatable, :registerable, :recoverable, :rememberableこれでdeviseのデフォルトのバリデーションも解除できました
結果はこちら
ちゃんと自分で設定したバリデーションだけが適用されていますね
*カスタムバリデーションの作成の仕方は最後の参考URLに載せておきますまとめ
- Railsのemail_fieldではメールアドレス用の簡単なバリデーションをかける仕様になっている
- deviseではデフォルトで簡単なバリデーションをかけるようになっている
- バリデーションの優先順位はemail_field > devise, カスタム(自作)
- カスタムバリデーションのみ適用させる場合は、text_fieldを使い、deviseの:validatableを削除する
Railsもdeviseも知らないところで色々と機能してくれてますが、少しずつそういう部分を理解していくことで、色々応用できそうですね
特にdeviseは便利ですが、意味を理解していないで使っている部分が多いと思ったので今回のようなケースはかなり勉強になりました余談ですが、password_fieldは入力した文字を"●"で秘匿化してくれてます
間違いなどがあれば指摘していただけると助かります
少しでも参考になった、勉強になったという方がいらっしゃれば幸いです参考URL
自作のカスタムバリデーションを作成する方法
- https://guides.rubyonrails.org/active_record_validations.html
- https://qiita.com/kouheiszk/items/215afa01eeaadbd99340
- 投稿日:2020-01-25T14:22:27+09:00
devise 導入直後のエラー(docker)
概要
[Rails] deviseの使い方(rails4版)
このサイト↑に沿ってdevise導入し、そこでこのエラーが発生しました。
その対処法を記載をしています。エラーの内容
ルーティングエラー
Rails routes で調べても特に問題なさそう・・
Rails: deviseをインストールした後のエラー
これ↑を実装したが、エラー治らず・・・対処法
問題は恐らくdockerなのでは?となり、とりあえず
docker再起動→ローカルを再起動docker再起動方法
右上にあるクジラを押す→restart 完了!!
それでもう一度localhostをリロードすると治りました。
お疲れさまでした!!
- 投稿日:2020-01-25T13:09:19+09:00
【rails】SystemSpec(capybara) on dockerでつまずいた時のメモ
Capyabaraの設定方法
https://qiita.com/ngron/items/f61b8635b4d67f666d75
上の記事をもとに設定解決したかったこと
Selenium::WebDriver::Error::UnknownErrorを解決して、systemtestを行う
失敗例
Gemfile.group :test do gem 'capybara', '>= 2.15' gem 'selenium-webdriver' end成功例
Gemfile.group :test do gem 'capybara' gem 'selenium-webdriver' end行ったこと
1、gem(capybara、selenium-webdriver)のバージョン固定を外す。
gemのバージョンを固定しているといつまでたってもエラー(Selenium::WebDriver::Error::UnknownError)が解決できない。
2、docker-compose build参考記事
Rails + Selenium + DockerでSystemSpecの環境構築
https://qiita.com/ngron/items/f61b8635b4d67f666d75ありがとうございます!!
- 投稿日:2020-01-25T12:32:40+09:00
【翻訳】URI.escapeは非推奨メソッドです。あなたのクエリ文字列をパーセントエンコードするには
この記事は以下のブログ記事の日本語訳です。
URI.escape is obsolete. Percent-encoding your query string
【翻訳】URI.escapeは非推奨メソッドです。あなたのクエリ文字列をパーセントエンコードするには
みなさんはRuby 2.7.0を使っているプロジェクトで以下の警告に遭遇しましたか?
warning: URI.escape is obsolete warning: URI.encode is obsoleteこの警告の直し方を見ていきましょう!
歴史について少しだけ
Ruby 2.7.0では
URI.escape
またはエイリアスメソッドのURI.encode
を呼びだしたときに警告が出ます。これはあたかも新しく追加された警告のように見えますが、実際はなんと・・・10年以上も非推奨とされ続けていたのです!どうしても今までこの警告を目にしなかったんだろう?と不思議に思っている方へ。答えはこうです。これまではverboseモードでスクリプトを実行したときだけ表示されていました。そして、この仕様が最近変わりました。これがその理由です。じゃあなんで
URI.escape
は非推奨メソッドなの?「URIをエスケープする」という概念は実はやっかいです。なぜならURIは多数の要素(
path
やquery
など)から成り立っており、その要素をすべて同じ方法でエスケープするわけではないからです。たとえば、#
という文字について考えてみましょう。この文字はURIの最後に出てくるときは問題ありません(これは世間ではアンカーと呼ばれます。URI用語で言うところのfragment
要素です)。しかし、ユーザー入力の一部に#
が使われたとき(たとえば検索キーワードなど)は、入力値を正しく解釈するためにそれをエンコードしたいと思うはずです。同様に、クエリ文字列に=
や&
といった予約文字が含まれていた場合、それらが間違って区切り文字として解釈されないようにエスケープしたくなるはずです(あたかも予約文字であるかのように)。
URI.escape
は単純にgsub
メソッドを使って文字列全体を置換しているだけです。各要素が何であるかは区別しません。なので、上で述べたような複雑な問題は一切考慮されないのです。どう修正するの?
URI文字列をまるごとを受け取って、各要素の違いをうまく解釈しつつ最適なエスケープ処理を加える、というような既存の解決策はまだ見つかっていません。ですので、私が考えるに、こういう場合は各要素を別々にエンコードするのが良いと思います。最も一般的な(そして最も問題が起きやすい)ユースケースは、おそらくクエリ文字列(
query
要素)のエンコーディングでしょう。そこで、今回はこのユースケースに焦点を当てます。RubyのURI
モジュールには2種類の便利なメソッドが用意されているので、これを使えばうまくいきます!クエリ文字列をパーセントエンコードする
URI.encode_www_form_component(string, enc=nil)このメソッドは
*, -, ., 0-9, A-Z, _, a-z
だけをそのまま残し、それ以外のすべての予約文字をパーセントエンコードします。さらに、スペースも+
に置換してくれます。以下の例を見てください。query = "Tom & Jerry" query = URI.encode_www_form_component(query) query # => "Tom+%26+Jerry"post = "So scared, but let's do this! #yolo" post = URI.encode_www_form_component(post) post # => "So+scared%2C+but+let%27s+do+this%21+%23yolo"ご覧のとおり、適切なエスケープ処理を加えて安全なクエリ文字列を作ることができました。しかし、これだとちょっと手間がかかりすぎると感じた場合は、クエリ全体を適切に処理してくれる便利な方法があります。それがこちらです。
URI.encode_www_form(enum, enc=nil)このメソッドは先ほどのメソッドとはインターフェースが若干異なり、
Enumerable
(通常はネストした配列かハッシュ)を受け取ります。それから、そのデータを使ってクエリ文字列を構築します。このメソッドは内部で.encode_www_form_component
を使うため、エンコーディング規則はどちらも同じです。異なるのは使い方だけです。以下の例を見てください。URI.encode_www_form([["search", "Tom & Jerry"], ["page", "3"]]) # => "search=Tom+%26+Jerry&page=3" URI.encode_www_form(["search", "2 + 2 = 5"]) # => "search=2+%2B+2+%3D+5" URI.encode_www_form(search: "why is URI.escape obsolete", category: "meta") #=> "search=why+is+URI.escape+obsolete&category=meta" # Shameless plug URI.encode_www_form(q: "how to speed up your CI?", tag: ["#devops", "#productivity"], lang: "en") #=> "q=how+to+speed+up+your+CI%3F&tag=%23devops&tag=%23productivity&lang=en"とても簡単ですね。
Railsの場合は?
Hash#to_query(
Hash.to_param
というエイリアスメソッドもあります)Railsは
Hash
クラスを拡張して、この便利なメソッドを追加しています。このメソッドは正しい形式でクエリ文字列を返します。値は適切にエスケープされます。query_data = { q: "how to speed up your CI?", tag: ["#devops", "#productivity"], lang: "en" } query_data.to_query #=> "lang=en&q=how+to+speed+up+your+CI%3F&tag%5B%5D=%23devops&tag%5B%5D=%23productivity"(キーがアルファベット順にソートされる点にも注意してください)
このメソッドにはオプション引数としてネームスペースを渡すこともできます。返ってくる文字列はネームスペースが各キーを内包する形になります。たとえば、
search[q]="how to speed up your CI?"
というような形です(もちろんパーセントエンコードされますが)。query_data = { q: "how to speed up your CI?", tag: ["#devops", "#productivity"], lang: "en" } query_data.to_query("search") #=> "search%5Blang%5D=en&search%5Bq%5D=how+to+speed+up+your+CI%3F&search%5Btag%5D%5B%5D=%23devops&search%5Btag%5D%5B%5D=%23productivity"まとめ
短い記事ですが、みなさんが「この記事を読んだらURI文字列のエンコードに関する疑問が解消された!」と思ってくれたら嬉しいです。もし、みなさんのRuby/Railsプロジェクトでは何か別の方法を使っているなら、コメント欄にてその方法も教えてください。
そしてもし、みなさんのプロジェクトでCIのビルドが遅いことにお困りでしたら、ぜひKnapsack Proをチェックしてみてください。その問題を解消します。
(翻訳はここまで)
訳者による補足
日本語や"%"が含まれる場合のエンコード結果について
クエリ文字列に日本語が含まれる場合や、文字列に
%
が含まれる場合のエンコード結果も調べてみました。
結果としてはURI.encode
を使った場合も、URI.encode_www_form_component
やURI.encode_www_form
を使った場合も同じでした。# 日本語をエンコードする場合 str = "あいう" URI.encode(str) #=> "%E3%81%82%E3%81%84%E3%81%86" URI.encode_www_form_component(str) #=> "%E3%81%82%E3%81%84%E3%81%86" URI.encode_www_form([['query', str]]) #=> "query=%E3%81%82%E3%81%84%E3%81%86"# %を含む文字列をエンコードする場合 str = "10%" URI.encode(str) #=> "10%25" URI.encode_www_form_component(str) #=> "10%25" URI.encode_www_form([['query', str]]) #=> "query=10%25"公式リファレンスのリンク等
各メソッドの公式リファレンスはこちらです。
また、公式リファレンスでは
URI.encode
の移行先として、encode_www_form_component
以外にも以下のようなメソッドが紹介されています。
- 投稿日:2020-01-25T12:21:34+09:00
Gem::MissingSpecVersionErrorでrails serverできない
問題
「rails server」を実行しようとしたら、エラーが出た。
$ rails server (Gem::MissingSpecVersionError) To update to the latest version installed on your system, run `bundle update --bundler`. To install the missing version, run `gem install bundler:2.1.2`解決策
以下のコマンドを実行する。
$ bundle update --bundler$ gem install bundler:2.1.2僕の場合、2つ目のコマンド「gem install bundler:2.1.2」でまたエラーが出たので対処する。
問題
「gem install bundler:2.1.2」を実行しようとすると、またエラーが出た。
$ gem install bundler:2.1.2 ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.解決策
まずはgemやrubyがどのパスを指しているのか現状の確認をする。
以下の結果からわかるように/usr/binというシステムのパスを指していることがわかる。$ which ruby /usr/bin/ruby$ which gem /usr/bin/gem調べると、システムのrubyを利用しているため、権限不足でgemのインストールができない可能性が高いみたいです。「gem installでpermissionエラーになった時の対応方法」が参考になりました。
rbenvでrubyを管理する
まずはrbenvのインストールする。
$ brew update $ brew install rbenv ruby-build続いて、rbenvの管理下にrubyをインストールする。
僕の場合は、Railsチュートリアルを進めているので、今回は2.6.1をインストールする。rbenv install 2.6.1globalで利用できるように変更する。
$ rbenv global 2.6.1rbenvにパスを通すため、シェルの設定ファイル(.bashrcや.zshrc)に以下を追加する。
[[ -d ~/.rbenv ]] && \ export PATH=${HOME}/.rbenv/bin:${PATH} && \ eval "$(rbenv init -)"シェルを再起動後、以下コマンドを実行して、もう一度gemとrubyのパスを確認してみる。
$ which ruby$ which gemはじめはシステムのパスを指していましたが、以下のようにrbenvのパスを指していることがわかる。
rails serverを実行する
$ rails server rbenv: rails: command not found The `rails' command exists in these Ruby versions: 2.7.0Railsが見つからない?と言ってそうなので、Railsのバージョンを指定してインストールする。
$ gem install -v 5.1.6 railsもう一度rails serverを実行する。
$ rails server . . . Use Ctrl-C to stop立ち上がったっぽいので、http://localhost:3000/にアクセスして画面が表示されるか確認する。
”無事に画像も表示されて、サーバーを立ち上げることができました!”
参考
- 投稿日:2020-01-25T10:24:47+09:00
【jQuery】RailsでValidation Pluginを使った動的なバリデーションチェックの実装 〜詳細実装/Bootstrap編〜
はじめに
前回の記事では導入編をまとめましたので本記事では詳細実装編をまとめます。後半では以下の場合についてもまとめています。
- Bootstrapを使用している場合
- deviseを使用している場合
- 正規表現チェックメソッドのサンプル一覧
開発環境
Ruby 2.5.1
Rails 5.0.7.2
jQuery 3.4.1
jQuery Validation Plugin 1.19.1
Bootstrap 4.3.1実装手順
入力フォームを実装済み、プラグインを導入済みであることを前提としています。
パスワードと確認用パスワードのバリデーションチェック
完成イメージ
解説・サンプルコード
eqaulToはデフォルトで使えるメソッドです。指定したidの入力欄と入力値が一致しているかをチェックできます。以下が本箇所のJSファイルの記述サンプルです。
jquery.validate.handler.user.js$(function () { // メソッドの定義 var methods = { password: function (value, element) { // パスワードの正規表現 return this.optional(element) || /^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}$/i.test(value); }, } // メソッドの追加 $.each(methods, function (key) { $.validator.addMethod(key, this); }); // バリデーションの実行 $("#signup-form, #charge-form").validate({ // ルール設定 rules: { "user[password]": { required: true, // 入力必須 password: true // 正規表現 }, "user[password_confirmation]": { required: true, // 入力必須 password: true, // 正規表現 equalTo: "#password" // パスワードと確認用パスワードが一致しているかチェック }, }, // エラーメッセージの定義 messages: { "user[password]": { required: "パスワードを入力してください", password: "英字と数字両方を含むパスワードを入力してください" }, "user[password_confirmation]": { required: "確認用パスワードを入力してください", password: "英字と数字両方を含むパスワードを入力してください", equalTo: "パスワードが一致していません" }, }, errorClass: "invalid", errorElement: "p", validClass: "valid", }); // 入力欄をフォーカスアウトしたときにバリデーションを実行 $("#password, #password_confirmation").blur(function () { $(this).valid(); }); });プルダウンリストの選択状況確認
プルダウンリストのバリデーションチェックを実装します。
OK/NGの基準を以下のように設けました。
- OK:プルダウンダウンリストが選択されて初期値から値が変わっている
- NG:初期値から値が変わっていない
sample.html.haml= form_tag(signup_index_path, method: :post, id:"charge-form", name: "inputForm", class: "pay_way__main__form") do %div.pay_way__main__form__content %div.pay_way__main__form__content__group %label.pay_way__main__form__content__group__label 有効期限 %span.pay_way__main__form__content__group__require 必須 .pay_way__main__form__content__group__expire .pay_way__main__form__content__group__expire__select %i.fas.fa-chevron-down.fa-lg.pay_way__main__form__content__group__expire__select__icon %select#exp_month{name: "exp_month", type: "text", class: "pay_way__main__form__content__group__expire__select__pulldown", name: "exp_month" } %option{value: ""} -- %option{value: "1"}01 %option{value: "2"}02 %option{value: "3"}03 %option{value: "4"}04 %option{value: "5"}05 %option{value: "6"}06 %option{value: "7"}07 %option{value: "8"}08 %option{value: "9"}09 %option{value: "10"}10 %option{value: "11"}11 %option{value: "12"}12 %span.pay_way__main__form__content__group__expire__select__text 月 .pay_way__main__form__content__group__expire .pay_way__main__form__content__group__expire__select %i.fas.fa-chevron-down.fa-lg.pay_way__main__form__content__group__expire__select__icon %select#exp_year{name: "exp_year", type: "text", class:"pay_way__main__form__content__group__expire__select__pulldown", name: "exp_year" } %option{value: ""} -- %option{value: "2019"}19 %option{value: "2020"}20 %option{value: "2021"}21 %option{value: "2022"}22 %option{value: "2023"}23 %option{value: "2024"}24 %option{value: "2025"}25 %option{value: "2026"}26 %option{value: "2027"}27 %option{value: "2028"}28 %option{value: "2029"}29 %span.pay_way__main__form__content__group__expire__select__text 年 #exp_date_errorjquery.validate.handler.user.js$(function () { // メソッドの定義 var methods = { valueNotEquals: function (value, element, arg) { // プルダウンリストが選択されているかの確認 return arg !== value; }, } // メソッドの追加 $.each(methods, function (key) { $.validator.addMethod(key, this); }); // バリデーションの実行 $("#charge-form").validate({ // ルール設定 rules: { exp_month: { valueNotEquals: "" }, exp_year: { valueNotEquals: "" } }, // エラーメッセージの定義 messages: { exp_month: { valueNotEquals: "有効期限を選択してください" }, exp_year: { valueNotEquals: "有効期限を選択してください" } }, groups: { //グループ化 exp_date: "exp_month exp_year" }, errorClass: "invalid", errorElement: "p", validClass: "valid", // エラーメッセージ表示位置のカスタム設定 errorPlacement: function (error, element) { if (element.attr("name") == "exp_month" || element.attr("name") == "exp_year") { error.insertAfter("#exp_date_error"); } else { error.insertAfter(element); } } }); // 選択欄をフォーカスアウトしたときにバリデーションを実行(ウィザードページ毎) $("#exp_month, #exp_year").blur(function () { $(this).valid(); }); });エラーメッセージの表示位置の設定
入力欄が横並びになっている場合、エラーメッセージはデフォルトでは各入力欄の直後にエラーメッセージが表示されます。そのため、入力欄が縦並びに変わってしまいます。そのようなときは本設定でメッセージの位置を指定できます。
完成イメージ
解説・サンプルコード
以下のようにエラーメッセージを表示させたい場所の直前にidを付与した要素を設けます。
sample.html.haml= f.text_field :lastname, class: "クラス名", placeholder:"例)山田", id: "lastname" = f.text_field :firstname, class: "クラス名", placeholder:"例)彩", id: "firstname" %div.#name_error # 〜エラーを表示させたい場所〜errorPlacementを使用して場所を指定します。
jquery.validate.handler.user.js$(function () { // バリデーションの実行 $("#signup-form").validate({ // ルール設定 rules: { "user[lastname]": { required: true }, "user[firstname]": { required: true } }, // エラーメッセージの定義 messages: { "user[lastname]": { required: "姓を入力してください" }, "user[firstname]": { required: "名を入力してください" }, errorClass: "invalid", errorElement: "p", validClass: "valid", // エラーメッセージ表示位置のカスタム設定 errorPlacement: function (error, element) { if (element.attr("name") == "user[lastname]" || element.attr("name") == "user[firstname]") { error.insertAfter("#name_error"); // 指定した要素の後ろにエラーを表示 } else { error.insertAfter(element); } } }); // 入力欄をフォーカスアウトしたときにバリデーションを実行 $("#lastname, #firstname").blur(function () { $(this).valid(); }); });Bootstrapを使用している場合
Bootstrapを使用している場合、バリデーションチェック後のクラス名追加にBootstrapのValidationのclass名を指定することで使用することができます。
Bootstrap 公式リファレンス(forms)
Bootstrap 日本語リファレンス(forms)完成イメージ
解説・サンプルコード
Bootstrapを適用したフォームを用意します。
app/views/devise/sessions/new.html.erb<div class="form-label-group"> <%= f.email_field :email, placeholder: "Email Address", class: 'form-control' %> <%= f.label :email %> </div> <div class="form-label-group"> <%= f.password_field :password, placeholder: "Password", class: 'form-control' %> <%= f.label :password %> </div>JSファイルでerrorClassとvalidClassを下記のように設定します。
jquery.validate.handler.user.js// 〜省略〜 errorClass: "is-invalid" validClass: "is-valid" // ~省略〜deviseを使用している場合
deviseを使用している場合でユーザー情報の変更において下記2つの入力パターンが想定されます。
- パスワードを変更しない場合:現在のパスワードの入力が必須
- パスワードを変更する場合:確認用パスワードが必須、現在のパスワードの入力は不要
バリデーションチェックを上記どちらでも対応できるように実装します。
完成イメージ
パスワードを変更しない場合:現在のパスワードの入力が必須
パスワードを変更する場合:確認用パスワードが必須、現在のパスワードの入力は不要
解説・サンプルコード
jquery.validate.handler.user.js// 〜省略〜 "user[password]": { // requiredは設定しない password: true }, "user[password_confirmation]": { // requiredは設定しない password: true, equalTo: "#user_password" // 新しいパスワードと一致しているか確認 }, "user[current_password]": { password: true, required: function (element) { // 新しいパスワード欄が空欄の場合は入力必須にする return $("#user_password").val() == ""; } }, // 〜省略〜正規表現チェックメソッド一覧
今回の開発で様々な正規表現チェックを実装したので、それもまとめたいと思います。
jquery.validate.handler.user.js// メソッドの定義 var methods = { email: function (value, element) { // メールアドレスの正規表現 return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/i.test(value); }, password: function (value, element) { // パスワードの正規表現 return this.optional(element) || /^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}$/i.test(value); }, phone: function (value, element) { // 電話番号の正規表現 return this.optional(element) || /^0\d{9,10}$/.test(value); }, // クレジットカード番号の正規表現 // VISA, MasterCard, Discover, Diners, Amex, JCBの番号規則に対応 cardNumber: function (value, element) { return this.optional(element) || /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47]{13}|(?:2131|1800|35[0-9]{3})[0-9]{11})$/.test(value); }, cvc: function (value, element) { // セキュリティコードの正規表現 return this.optional(element) || /^\d{3,4}$/.test(value); }, postalCode: function (value, element) { // 郵便番号の正規表現 return this.optional(element) || /^\d{3}[-]\d{4}$/.test(value); }, kana: function (value, element) { // カタカナの正規表現 return this.optional(element) || /^[ァ-ヴ]+$/.test(value); }, }まとめ
デフォルトで様々なメソッドが準備されていますが、カスタムメソッドを作ることができるため様々なバリデーションチェックが実装できます。Bootstrapのクラス名を組み込めばBootstrapと連携可能です。
参考URL
正規表現を可視化してまとめたチートシート
jquery.validate.jsでセレクトボックスのチェック、他カスタマイズ色々
- 投稿日:2020-01-25T10:15:13+09:00
【Rails】 独自 Validation 作成方法(複数モデル適用)
はじめに
バリデーションの作成方法はモデル内にprivateメソッドを作って、そのメソッドをvalidateの引数に指定する方法が一般的かと思います。
今回は、複数のモデルで同じバリデーションを適用したいケースへの対応方法をまとめました。独自バリデーション作成方法
やること
開始日時カラムと終了日時カラムを持ったモデルの入力フォームに、
どちらのカラムも入力するか、どちらのカラムも入力しないバリデーションをかけたい。Concern
まずは、
app/models/concerns
の直下にバリデーション専用のクラスを作成する。
Concernsを使用することで、同じカラムを持った他のモデルにも適用することができ、さらに細かい継承関係を考えなくてもよくなります。app/models/concerns/work_datetime_validation.rbclass WorkDatetimeValidation < ActiveModel::Validator # record には、インスタンスが入る def validate(record) return if record.work_datetime_begin && record.work_datetime_end return if !record.work_datetime_begin && !record.work_datetime_end record.errors[:base] << '開始日時と終了日時どちらも入力するか、どちらも空にしてください' end endModel
次にModelに
validates_with
を用いて、先ほど作成したクラスを指定する。他のModelにも適用させたい場合は、
validates_with
を他のクラスに書けばバリデーションが適用されます。app/models/work.rbclass Work < ApplicationRecord validates_with WorkDatetimeValidation end以上となります。
まとめ
時間に関するバリデーションは複数のモデルで使用したいというニーズがあると思いますので、ぜひ活用してみてください。
- 投稿日:2020-01-25T10:04:34+09:00
Railsアプリ起動時に突然「Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)」になった時の対処法
はじめに
Railsアプリをローカルで起動させた際に、MySQLのConnectionErrorが発生しました。先日まで問題なく起動していたのですが……。
mysqlサーバーに接続する際、mysql.sockファイルを使って接続するらしいのですが、
なんらかの原因により、このファイルが消えることがあるそうです。
エラー文で指定されているところに、mysql.sockファイルを作成して再度接続してみました。$ sudo touch /tmp/mysql.sock $ sudo mysql.server restart Starting MySQL . ERROR! The server quit without updating PID file (/usr/local/var/mysql/MBP-2.local.pid).エラー画面の
(2)
が(38)
に変わっただけです。
検索するとこの類のエラーは結構頻発するらしく、まずは権限周りから触ってみました。$ sudo chown mysql:mysql /tmp $ sudo chmod 777 /tmp/mysql.sock $ mysql.server start Starting MySQL ... ERROR! The server quit without updating PID file (/usr/local/var/mysql/MBP-2.local.pid). $ sudo touch MBP-2.local.pid $ sudo rm /tmp/mysql.sock $ chown -R _mysql:_mysql mysql $ sudo chown UserName /tmp/mysql.sock $ mysql.server start Starting MySQL .. ERROR! The server quit without updating PID file (/usr/local/var/mysql/マシン名.local.pid).以上の内容を色々試してみたのですが解決せず。Macを再起動しても何も変化なしでした。
MySQLをhomebrewでインストールしていたので/usr/local/var/mysql
をディレクトリごと消去して再インストールしました。$ sudo rm -rf /usr/local/var/mysql $ brew uninstall mysql@5.7 Uninstalling /usr/local/Cellar/mysql@5.7/5.7.28... (319 files, 232.2MB) $ brew install mysql@5.7 ・ ・ mysql@5.7 is keg-only, which means it was not symlinked into /usr/local, because this is an alternate version of another formula. If you need to have mysql@5.7 first in your PATH run: echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.zshrc ・ ・ ? /usr/local/Cellar/mysql@5.7/5.7.29: 319 files, 232.3MB再インストールだけだとパスが通っていないのでexportコマンドでパスを通すように設定します。
$ echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.zshrc $ sudo vi ~/.zshrc export PATH=/usr/local/bin:$PATH export PATH="$HOME/.rbenv/bin:$PATH" eval "$(rbenv init -)" export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" $ source ~/.zshrcまずはMySQLがインストールされているか確認します。
$ mysql --version mysql Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using EditLine wrapper続いてMySQL5.7を起動させます。
$ brew services start mysql@5.7 ==> Successfully started `mysql@5.7` (label: homebrew.mxcl.mysql@5.7)起動させるRailsアプリのデータベース設定ファイルは以下のようになっています。
database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: test-user password: password-example socket: /tmp/mysql.sock指定しているユーザーでMySQLに接続してみます。
$ mysql -u test-user -ppassword-example ERROR 1045 (28000): Access denied for user 'test-user'@'localhost' (using password: YES)接続エラーとなりました。MySQLを再インストールしたためにtest-userが消去されているようです。
試しに現在のユーザーリストを確認すると、$ mysql -u root -p ・ ・ ・ mysql> SELECT user, host FROM mysql.user; +------------------+-----------+ | user | host | +------------------+-----------+ | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +------------------+-----------+ 4 rows in set (0.00 sec)確かに、ユーザーリストに
test-user
が存在していませんので再度ユーザーを作成します。$ mysql -u root -p ・ ・ ・ mysql> CREATE USER 'test-user'@'localhost' IDENTIFIED BY 'password-example'; Query OK, 0 rows affected (0.12 sec) mysql> SELECT user, host FROM mysql.user; +------------------+-----------+ | user | host | +------------------+-----------+ | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | | test-user | localhost | +------------------+-----------+ 5 rows in set (0.00 sec)ユーザーの作成ができたので権限付与も合わせて行います。今回はテストなので全てのデータベースにアクセスできる権限を付与しました。
mysql> GRANT ALL ON *.* TO 'test-user'@'localhost'; Query OK, 0 rows affected (0.05 sec)再度、MySQLに接続してみます。
$ mysql -u test-user -ppassword-example mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. ・ ・ ・ mysql>接続できましたので、続いてデータベースを作成します。
$ bundle exec rails db:create Created database '[アプリケーション名]_development' Created database '[アプリケーション名]_test'未実行のマイグレーションファイルを全て実行し、データベースにテーブルを作成します。
$ bundle exec rails db:migrare == 20200117122858 DeviseCreateUsers: migrating ================================ -- create_table(:users) -> 0.0093s -- add_index(:users, :email, {:unique=>true}) -> 0.0302s ・ ・ ・以上で設定終了です。再度Railsアプリを立ち上げてみます。
無事に立ち上がりました。急にエラーが出て結構焦りましたが、いい勉強になりました。
参考記事
https://qiita.com/tosite0345/items/3f346780e14feca48f55
https://weblabo.oscasierra.net/mysql-57-homebrew-install/
https://qiita.com/gatapon/items/92b942fa7081cfe17482
https://qiita.com/kskumgk63/items/b308c0a688c358b17162
https://qiita.com/pugiemonn/items/718b7360028286c5b626
- 投稿日:2020-01-25T09:28:19+09:00
Rails6 データベースのカラム作成を行う際の概要
目的
- カラムを作成したり削除したりする時の概要をまとめる
間違えてマイグレートしてしまった時はこちらを参考にロールバックを行う
Rails6 マイグレーションファイルの記載ミスでマイグレートしてしまったらrollbackを使おう
作業概要(カラムを追加する)
- カラムを追加するテーブル名を確認
- 追加するカラム名と型を決定
- マイグレーションファイルの作成
- 追加カラム情報の記載
- マイグレート
作業詳細(カラムを追加する)
- カラムを追加するテーブル名を確認
- これからカラムを追加するテーブル名を確認する。
- 追加するカラム名と型を決定
- 追加する任意のカラム名とデータ型を決める。
マイグレーションファイルの作成
下記コマンドを実行してマイグレーションファイルの作成を行う。
$ cd Railsで作成したアプリのルートフォルダ $ rails g migration change_カラムを追加するテーブル名_columns
アプリ名/db/migrate
直下にYYYYMMDDHHMM_change_カラムを追加するテーブル名_columns.rb
というマイグレーションファイルが作成される。追加カラム情報の記載
先に作成された
YYYYMMDDHHMM_change_カラムを追加するテーブル名_columns.rb
ファイルにカラムを追加する記載を記入する。 下記にusers
テーブルにpassword_digest
カラムをstring
型で追加する時の記載の例を書くclass ChangeUsersColumns < ActiveRecord::Migration[6.0] def change add_column :users, :password_digest, :string end endマイグレート
下記コマンドを実行してマイグレートを行う。
$ rails db:migrate
- 投稿日:2020-01-25T02:09:36+09:00
Rubyではメソッドにreturnの記述要らない?
Railsで開発している際に既存コードにreturnが書かれていなかったり、returnを書いてrubocopに指摘されたりしたので調べました。
rubyでは不要であればreturnは書かない方針のようです。RubyではReturnの記述は不要
Rubyのメソッドでは、最後に評価された値が返るという仕様になっています。
例えば以下のような文字列を返すメソッドがあります。def hoge(is_hoge) if is_hoge "hoge" else "fuga" end end最後に評価された値が返るので、それぞれ以下を返します。
hoge(true) # "hoge" hoge(false) # "fuga"後置ifでは注意が必要
例
def hoge(is_hoge) "fuga" "hoge" if is_hoge endhoge(true) # "hoge" hoge(false) # nilなんとなく
hoge(false)
でfugaが帰って来そうですが、最後で評価された値が返るのでnilが帰ってきます。後置ifでは、ifの右側の値が評価されたあと、trueならば左側が評価されます。
falseであればnilを返します。例の場合、
hoge(false)
でif is_hoge
は成立しないので、左側のfugaは評価されず、
"hoge" if is_hoge
が最後に評価された値となり、nilを返します。
- 投稿日:2020-01-25T01:38:57+09:00
Rails4系で統合テストをDocker環境内で行う
はじめに
今回Railsのバージョンアップに向けて不足していた箇所のテストを書いていました。
その一環で統合テストを書こうとして軽く詰まったので似たような境遇方のためになればと思い(こんなレアケースに遭遇する人は少ないと思いますが)記事にしました。なぜ統合テストなのか
プロダクトで使用している外部サービスのAPIがjsにしか対応しておらず、プロダクト内で重要な機能の一部に組み込まれていたため。
環境
Rails 4系
Ruby 2.5.7
Rspec 3.9.1
capybara 3.30.0対象
- すでにRspecのテスト環境が整っている。
- dockerを用いて開発を行なっている。
- dockerを用いていない場合はローカルにインストールされているブラウザを使用すれば簡単に実装できると思います。
Railsアプリケーションが入っているコンテナにchromeなどを導入する
ブラウザ用にコンテナを分けるか迷いましたが、circleciにブラウザが導入されているRubyのイメージがあったため開発環境下でもRailsアプリケーションが入っているコンテナに導入することにしました。
Dockerfileに以下のchromeやseleniumなどをインストールするためのコマンドを書き足します。
DockerfileFROM ruby:2.5.7 # 下記の内容については現在の設定内容に合わせて変更してください。 # googleが用意している公開鍵をaptに追加 RUN wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - # aptに安定版chromeがインストールできるレポジトリgoogle-chrome.listを追加します。 RUN echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list # aptで必要なパッケージをインストールします。 # seleniumをpipでインストールするため一緒にインストールします。 RUN apt-get update -qq && apt-get install -y [nodejsやRDBMSのクライアントなど] google-chrome-stable python3-pip # seleniumでchromeを動かすためのchromedriverをダウンロードします。 # installしているchromeのバージョンに対応したchromedriverをインストールする必要があるため # http://chromedriver.storage.googleapis.com/LATEST_RELEASE # でchromeの安定バージョンを取得することができるため、その値を用いてchromedriverのバージョンを指定しています RUN LATEST_RELEASE=$(curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE) &&\ wget http://chromedriver.storage.googleapis.com/$LATEST_RELEASE/chromedriver_linux64.zip # ダウンロードしたchromedriverを解凍します。 このときPATHが通っている階層に配置しましょう。 RUN unzip chromedriver_linux64.zip -d /bin/ # pipでseleniumをインストールします。 RUN pip3 install selenium # これより下はRailsのインストールなど既存のコードになるかと思います。Rails側で統合テストを動かす設定
Gemfileに以下を追加
Gemfilegem 'selenium-webdriver'rails_helper.rbに以下を追加
rails_helper.rbrequire 'selenium-webdriver'以下の内容を設定ファイルを作成して記述する。(rails_helper.rbなどに書いても可)
spec/support/capybara.rbCapybara.register_driver :selenium do |app| option = Selenium::WebDriver::Chrome::Options.new( args: %w[--headless --disable-gpu --no-sandbox] ) Capybara::Selenium::Driver.new( app, browser: :chrome, options: option, timeout: 600, # この設定がないとテスト内容によってはcircleciで Net::ReadTimeout となってしまう desired_capabilities: { accept_insecure_certs: true } ) end Capybara.javascript_driver = :selenium以上の設定で統合テストが実行できる環境が出来上がったと思います。
さいごに
Rails4系で統合テストのやり方を調べるとcapybara-webkitを使用した記事しか出てこなかったり、良さげなやり方を見つけてもsystem testに対応していなかったりとなにから導入していいのか調べるところからで少し詰まってしまいました。。。
また、せっかくdockerを使用しているので初めはブラウザ用のコンテナを用意しましたがコンテナ間の接続に証明書が必要でした。
証明書の発行まで書こうかと思いましたがcircleciでブラウザーが含まれたimage(今回だとcircleci/ruby:2.5.7-node-browsers)があったため分けずに構築してみました。
初めての内容ばかりだったのでおそらく改善できる点がたくさんあると思います。
改善点や気になったことがあればコメントで教えていただけると嬉しいです!参考記事
https://qiita.com/zo30005/items/a5dcede868a3d1cca4a8
https://www.google.com/linuxrepositories/
https://www.linuxbabe.com/ubuntu/install-google-chrome-ubuntu-18-04-lts
https://circleci.com/docs/2.0/circleci-images/#language-image-variants
- 投稿日:2020-01-25T01:05:16+09:00
joinsで結合したモデルのscopeを使ってデータを取得する方法
inner joinかつ別モデルのscopeを利用してそのモデルの状態を条件にデータを取得したい。
例えば、「紐づくuserのstatusがtrueであるtweet」を取得したいときは以下のように書ける。Tweet.joins(:user).merge(User.available)user.rb
class User < ApplicationRecord has_many :tweets scope :available, -> { where(status: true) } endtweet.rb
class Tweet < ApplicationRecord belongs_to :user end