- 投稿日:2021-01-16T23:38:47+09:00
link_toメソッドのクリックできる部分を拡大させたい
はじめに
link_toメソッドを使って、ページ遷移をしているが、クリックできる部分が文字のところだけだったことに不満を感じたので、調べて実装しました。
CSSでブロック要素に変えて、padding
link_toメソッドにクラス名をつけます。
つける時はclass: "クラス名"
そのクラス名に対して、CSSでdisplay: block;
のスタイルをつけます。
さらに、paddingで範囲を広げると、クリックできる部分が拡大します。ちなみに、marginしてもクリックできる部分は広がりません。
erb<ul> <li class="menu-list"> <%= link_to 'マイページ', hoge_path, class: "menu-name" %> </li> <li class="menu-list"> <%= link_to 'カレンダー', hoge_path, class: "menu-name" %> </li> </ul>css.menu-list { margin: 30px auto; border: black 3px solid; padding: 0px; } .menu-name { display: block; padding: 30px; }
display: block;とpadding
が大事な部分です。
- 投稿日:2021-01-16T22:49:18+09:00
carrierwaveでpdfファイル投稿機能をつける
はじめに
前回書いた記事でも触れたのですが、carrierwaveを用いてRailsアプリにpdf投稿機能をつけたのでその際に行った手順を備忘録として残しておきます。
carrierwaveの導入
gemfileに、下の1行を加えてbundle installします。
gemfilegem 'carrierwave'dbにfileカラムを追加
今回、送信されたデータをdbに保存するために、元々作っていたpostsテーブルにfileカラムを追加しました。マイグレーションファイルを作ってカラム追加しただけなのでコマンドは割愛します。
carrierwaveクラスの作成
carrierwaveを使うには、専用のクラスを作る必要があります。使い方の概要は以下の記事を参考にしました。
https://pikawaka.com/rails/carrierwave以下、上記ページとほぼ同じではありますが自分が行った手順をまとめます。
bin/rails g コマンドでcarrierwaveクラスを生成
terminalbundle exec rails g uploader アップローダー名以下の場所 app/uploaders/アップローダー名_uploader.rb に作られた設定ファイルで次のように記述します。
app/uploaders/アップローダー名_uploader.rbclass アップローダークラス < CarrierWave::Uploader::Base #保存場所の設定 storage :file #保存するフォルダの設定 def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end今回はpublic配下のuploadsフォルダ内に投稿されたpdfファイルを保存します。デプロイの際は外部のストレージサービスへの指定にしたりもできるようです。
アップローダークラスとモデルの紐付け
クラスと関連づけたいモデルで、以下の記述をします。
モデル名.rbclass モデル名 < ActiveRecord::Base mount_uploader :関連付けたいカラム名, アップローダークラス endフォームにfile_fieldを追加&dbに保存
パラメーターでfile_fieldの情報をfileカラムに保存するようにしました。(保存場所はご自分の任意の保存したいカラムで構いません)コントローラーでいつも通り記述するだけなので割愛します。
viewで表示する
viewで次の記述をします。
app/views/任意のview<object data="<%= @post.file.url %>" type="application/pdf" width="200" height="300"></object>@postはこのviewをレンダリングするアクションで定義したpostモデルのインスタンス変数で、fileというカラムを持っています。そこに、carrierwaveで生成したアップローダークラスが持つurlメソッドを用いて、ファイルまでのurlを指定しています。(自分で設定したモデル、カラム名に適宜置き換えてください。) width, height で表示するサムネイルのサイズを指定できます。
以上で表示できました!
終わりに
サムネイル生成の方法はobjectを使うもの以外もあるようなので気になる方は調べてみるとよいかもしれません。僕はサムネイルがなかなか実装できずcarrierwaveのエラーだと思っていたらform_withの指定ミスだったので、もし詰まっている方はそちらも確認してみるとよいかもです。
- 投稿日:2021-01-16T21:57:03+09:00
RubyOnRails、Authentication plugin 'caching_sha2_password' cannot be loadedエラーの解決法
RubyOnRails、Authentication plugin 'caching_sha2_password' cannot be loadedエラーの解決法
Ruby on rails 開発時に、databaseをmysql 8.0に設定してしたく、database.ymlをmysql設定の上で、rails db:migrate を実行したところ、エラー「Authentication plugin ‘caching_sha2_password’ cannot be loaded」となった時の解決法を共有します。
*laravelにも同様のエラーが発生するとの。環境の整理
- 開発環境:Windows10 Home 64ビットオペレーティングシステム、x64ベースプロセッサ
- Rails version 5系
- Mysql
- version 8.0
- user: root
- password: root(=今回の例)
- RubyOnRailsのdatabase.yml設定状況
原因
mysql 8.0以降に、認証方式がcaching_sha2_passwordを使うようになったこと。
しかし、Railsはこれに対応していなかったこと。方法
対象のユーザーの認証方式を「caching_sha2_password」から「mysql_native_password」に変更する。
今回をuserがrootの認証方式を変更する。
mysql -u root -p
でmysqlにアクセスするroot
(今回のpassword)を入力、Enterする。
SELECT user, host, plugin FROM mysql.user;
でユーザー一覧を表示させ、確認する。
ALTER USER root IDENTIFIED WITH mysql_native_password BY 'root';
を実行する。
- 構文:
ALTER USER ユーザー名 IDENTIFIED WITH mysql_native_password BY 'password';
SELECT user, host, plugin FROM mysql.user;
でrootの認証方式が変更されていることを確認する。
exit
でmysqlから抜ける
rails db:migrate
で本題のrailsのmigrateコマンドを実行する。*補足:
my.ini(macだとmy.cnf)にて、
default_authentication_plugin=caching_sha2_password
を
default_authentication_plugin=mysql_native_password
に変更すると、エラーが消えるとの話もあったが、
変更したあとでmysqlを再起動しても変更されなかった。
ちなみに、my.iniの場所は「C:\ProgramData\MySQL\MySQL Server 8.0」である。
- 投稿日:2021-01-16T21:26:04+09:00
formオブジェクトでタグ付け機能を実装
実装の流れ
tagモデルと中間テーブルを作成
投稿とタグは多対多の関係になるため、中間テーブルを作成します。
投稿のモデルを作成します。
$ rails g model item name:string user:referencesタグモデルを作成します。
$ rails g model tag word:string中間テーブルを作成します。
$ rails g model item_tag_relation item:references tag:referencesマイグレーションファイルを確認します。
db/migrate/create_items.rbclass CreateItems < ActiveRecord::Migration[6.0] def change create_table :items do |t| t.string :name t.references :user, foreign_key: true t.timestamps end end enddb/migrate/create_tags.rbclass CreateTags < ActiveRecord::Migration[6.0] def change create_table :tags do |t| t.string :word t.timestamps end end enddb/migrate/create_item_tag_relations.rbclass CreateItemTagRelations < ActiveRecord::Migration[6.0] def change create_table :item_tag_relations do |t| t.references :item, foreign_key: true t.references :tag, foreign_key: true t.timestamps end end endunique: trueで同じタグ名を登録しないようにできますが、うまく実装できなかったので別の方法で一意性を持たせました。
$ rails db:migrate
モデルの関連付けとバリデーション
app/models/item.rbclass Item < ApplicationRecord has_many :item_tag_relations has_many :tags, through: :item_tag_relations, dependent: :destroy belongs_to :user end「has_many :tags, through: :item_tag_relations」の記述にによって、item_tag_relationsモデルを通してアイテムに紐づくタグを取得します。
app/models/tag.rbclass Tag < ApplicationRecord has_many :item_tag_relations, dependent: :destroy has_many :items, through: :item_tag_relations validates :word, uniqueness: true end「validates :word, uniqueness: true」の記述によって、タグの名前が重複して登録されるの防ぎます。(何故かうまく働きませんでした...)
app/models/item_tag_relation.rbclass ItemTagRelation < ApplicationRecord belongs_to :item belongs_to :tag end
ルーティングを設定
config/routes.rbRails.application.routes.draw do root to: 'items#index' resources :items end
formオブジェクトの作成
Formオブジェクトは、1つのフォーム送信で複数のモデルを更新するときに使用するツールです。自分で定義したクラスをモデルのように扱うことができます。
modelsディレクトリ配下に「app/models/item_tag.rb」ファイルを作成します。
app/models/item_tag.rbclass ItemTag include ActiveModel::Model attr_accessor :name, :user_id, :item_id, :tag_ids endActiveModel::Modelをincludeすることで、そのクラスのインスタンスはActiveRecordを継承したクラスのインスタンスと同様に form_with や render などのヘルパーメソッドの引数として扱えたり、バリデーションの機能が使えるようになります。
attr_accessorで使用したいカラム名をセットします。
続いて、フォームからパラメーターとして送られてきた情報をテーブルに保存する処理を追加します。
app/models/item_tag.rbclass ItemTag include ActiveModel::Model attr_accessor :name, :user_id, :item_id, :tag_ids def save @item = Item.create(name: name, user_id: user_id) tag_list = tag_ids.split(/[[:blank:]]+/).select(&:present?) tag_list.each do |tag_name| @tag = Tag.where(word: tag_name).first_or_initialize @tag.save unless ItemTagRelation.where(item_id: @item.id,tag_id: @tag.id).exists? ItemTagRelation.create(item_id: @item.id, tag_id: @tag.id) end end end endアイテムの情報を保存し「@item」という変数に代入しています。
tag_list = tag_ids.split(/[[:blank:]]+/).select(&:present?)は入力フォームのf.text_fieldから送られたタグをtag_idsとしてparamsで送信します。
そして、split(/[[:blank:]]+/)によってtag_ids内の文字列を空白で区切り、バラバラの単語にして配列に入れていきます。
最後に、select(&:present?)は、配列化した値をそれぞれpresent?メソッドで判定して、真であれば取り出します。
@tag = Tag.where(word: tag_name).first_or_initializeで新規タグか既存タグかの判別をします。
判別をして既存タグなら既存のidを使用。新規ならidを生成します。
unless ItemTagRelation.where(item_id: @item.id,tag_id: @tag.id).exists?は今回重複したタグを保存できないようにしたかったのですが、バリデーションやマイグレーションファイルに一意性を持たせても保存されてしまったので、苦肉の策でモデルにて対処しました。
ItemTagRelation.where(item_id: @item.id,tag_id: @tag.id).exists?で、中間テーブルであるitem_tag_relationモデルの投稿に対して、同じ名前のタグが存在していないかを.exists?で判定しています。
タグが重複した場合はtureになるのでunlessで条件式をかけています。
controllerの処理
$ rails g controller itemsapp/controllers/items_controller.rbdef new @item = ItemTag.new end def create @item = ItemTag.new(itemtags_params) if @item.valid? @item.save redirect_to items_path(@item) else render :new end end private def itemtags_params params.require(:item_tag).permit(:name, :text, :image, :tag_ids).merge(user_id: current_user.id) endformオブジェクトに対してnewメソッドを使用しています。
viewの作成
関連する所のみ記述します。
app/views/items/new.html.erb<%= form_with model: @item, url: items_path, local: true do |f| %> <%= f.text_field :tag_ids %> <%= f.submit "投稿する" %>tag_idsはitemモデルで「 has_many :tags, through: :item_tag_relations」の関連付けをすることよってアイテムオブジェクトに使用できるようになります。
ひとまずこれで、タグ付け機能を実装できます。
参考にさせていただいた記事
【Ruby on Rails】タグ検索機能を実装してみた
https://qiita.com/E6YOteYPzmFGfOD/items/177f18e706df05f9b42e初心者が手探りで Rails のタグ付機能を gem なしで実装してみる
https://qiita.com/ryutaro9595/items/042a1ec713c8c1f2c1d6rails 投稿記事にタグをつける機能を実装する。
https://shirohige3.hatenablog.com/entry/2020/11/08/013327
- 投稿日:2021-01-16T21:25:49+09:00
【CircleCI2.0】JavaScript に対応するように設定
はじめに
CircleCI で JavaScript を扱えるように設定しました。
今まで問題なく動作していたCircleCI
のテストでしたが、あることをしてから通らなくなったので対処方法を記していきます。今までの設定ファイルはこちらです。
目次
環境
問題
原因
- RSpecで
js: true
を使用- 今回 ローカル環境と CircleCI環境 をあわせるために行った変更
解決策
spec/support/capybara.rb
- 変更前
- 変更後
spec/rails_helper.rb
Dockerfile
.circleci/config.yml
.circleci/config.yml 全体
config/database.yml.ci
まとめ
おわりに
参考文献
環境
- Ruby: 2.6.6
- Bundler: 2.0.2
- MySQL: 8.0
- CircleCI: 2.0
問題
SocketError: Failed to open TCP connection to chrome:4444 (getaddrinfo: No address associated with hostname) # chrome:4444へのTCP接続のオープンに失敗SocketError: getaddrinfo: No address associated with hostname # ホスト名に関連付けられたアドレスはありません原因
RSpecでjs: trueを使用
RSpecで JavaScriptのテストを実装 したところローカル環境で通っていたテストがCircleCIの自動テストでは通りませんでした。
結論として、ローカル環境とCircleCIの環境の差異が原因かと思います。
ローカルではchromeコンテナを立ち上げてSystem Spec
を通していましたが、CircleCI の設定ファイル
でも設定が必要なのでエラーが起きていました。今回ローカル環境とCircleCI環境をあわせるために行った変更
- chromeコンテナ から Dockerfileで chrome を追加するようにしたこと
- Chrome使用時のURLを指定していたので削除したこと
CircleCI の設定ファイル
で Chrome の追加と background で使用するようにしたこと解決策
spec/support/capybara.rb
大幅に変更したように見えますが、
url
を指定していないというのがポイントです。変更前require 'capybara/rspec' require 'selenium-webdriver' module CapybaraSupport Capybara.javascript_driver = :selenium_chrome_headless Capybara.default_driver = :selenium_chrome_headless Capybara.register_driver :selenium_chrome_headless do |app| url = 'http://chrome:4444/wd/hub' caps = ::Selenium::WebDriver::Remote::Capabilities.chrome( 'goog:chromeOptions' => { 'args' => [ 'no-sandbox', 'headless', 'disable-gpu', 'window-size=1680,1050' ] } ) Capybara::Selenium::Driver.new(app, browser: :chrome, url: url, desired_capabilities: caps) end変更後require 'capybara/rspec' require 'selenium-webdriver' Capybara.register_driver :selenium_chrome_headless do |app| options = ::Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--window-size=1400,1400') driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) end Capybara.javascript_driver = :selenium_chrome_headlessspec/rails_helper.rb
RSpec.configure do |config| config.before(:each, type: :system) do driven_by :rack_test end config.before(:each, type: :system, js: true) do driven_by :selenium_chrome_headless end endDockerfile
ローカル環境のテストで Chrome を使用したいので
Dockerfile
で Chromeの追加 をしています。
この記述をRUN mkdir /myapp
の前に書きました。RUN apt-get update && apt-get install -y unzip && \ CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \ wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ && \ unzip ~/chromedriver_linux64.zip -d ~/ && \ rm ~/chromedriver_linux64.zip && \ chown root:root ~/chromedriver && \ chmod 755 ~/chromedriver && \ mv ~/chromedriver /usr/bin/chromedriver && \ sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \ apt-get update && apt-get install -y google-chrome-stable # ルート直下にmyappという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ) RUN mkdir /myapp WORKDIR /myapp.circleci/config.yml
CircleCIの設定ファイル。Chromeを追加 することで ローカル環境との差異 をなくすようにしました。
steps: - run: name: Chrome Driver Install command: | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install -y unzip wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/ unzip ~/chromedriver_linux64.zip -d ~/ rm ~/chromedriver_linux64.zip sudo chown root:root ~/chromedriver sudo chmod 755 ~/chromedriver sudo mv ~/chromedriver /usr/bin/chromedriver sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -' sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' sudo apt-get update && sudo apt-get install -y google-chrome-stable background: true.circleci/config.yml 全体
RSpecを動かすところで
no_output_timeout: 15m
と記述しています。
こちらはなくともテストには直接関係ないので削除しても大丈夫です。なにも設定しなければ標準で10分の制限時間があり、それを過ぎるとタイムアウトエラーになってしまうので念の為付けております。テストの数とかにもよると思いますが、実際にはほんの数分で終わるので不要です。
version: 2 jobs: build: docker: - image: circleci/ruby:2.6.6-node-browsers environment: - BUNDLER_VERSION: 2.0.2 - RAILS_ENV: 'test' - image: circleci/mysql:8.0 command: [--default-authentication-plugin=mysql_native_password] environment: - MYSQL_USER: root - MYSQL_DB: ci_test - MYSQL_ROOT_HOST: "127.0.0.1" working_directory: ~/myapp steps: - run: name: Chrome Driver Install command: | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install -y unzip wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/ unzip ~/chromedriver_linux64.zip -d ~/ rm ~/chromedriver_linux64.zip sudo chown root:root ~/chromedriver sudo chmod 755 ~/chromedriver sudo mv ~/chromedriver /usr/bin/chromedriver sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -' sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' sudo apt-get update && sudo apt-get install -y google-chrome-stable background: true - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "Gemfile.lock" }} - v1-dependencies- - run: name: install dependencies command: | gem install bundler -v 2.0.2 bundle install --jobs=4 --retry=3 --path vendor/bundle - save_cache: key: v1-dependencies-{{ checksum "Gemfile.lock" }} paths: - ./vendor/bundle - run: mv config/database.yml.ci config/database.yml - run: yarn install - run: bundle exec rake db:create - run: bundle exec rake db:schema:load - run: name: run tests command: | mkdir /tmp/test-results TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \ circleci tests split --split-by=timings)" bundle exec rspec \ --format RspecJunitFormatter \ --out /tmp/test-results/rspec.xml \ --format progress \ $TEST_FILES no_output_timeout: 15m - store_test_results: path: /tmp/test-results - store_artifacts: path: /tmp/test-results destination: test-resultsconfig/database.yml.ci
test: adapter: mysql2 encoding: utf8 pool: 5 username: 'root' port: 3306 host: '127.0.0.1' database: ci_testまとめ
Dockerfile
とCircleCIの設定ファイル
で Chromeを追加- ローカルで通用してもCircleCI上で失敗することがある。
- ありがたいことに記事(情報)がたくさんあるので、その中で自分がどの問題に直面しているのかを理解することが大事。
おわりに
前回の記事に変更前の
CircleCIの設定ファイル
があります。(厳密に言えば少しリファクタなどしています)
JavaScript適用前 ですが、CircleCI
についてまとめていますのでよろしければご覧ください。参考文献
- 投稿日:2021-01-16T19:58:23+09:00
deviseメール認証時、認証メールに画像を挿入する --備忘録--
前提
deviceのログイン機能
【Rails】deviseを導入してみる
メールの認証機能
【devise】メール認証のサインアップ・イン・アウト機能
devise でメール認証を実装したい【Rails】上記2つの機能を実装済みです。
mailerをオーバーライドし、メソッドを作成
「app/controllers/users」に「mailer.rb」を作成します。
deviceのmailerを継承します。mailer.rbclass Users::Mailer < Devise::Mailer end「config/initializers/devise.rb」の設定をします
devise.rbconfig.mailer = 'Users::Mailer'挿入したい画像を「/app/assets/images/mailer/」に入れる。
先ほど作成した「mailer.rb」にHTML形式のメールにで挿入する為のメソッドを追記する。mailer.rbclass Users::Mailer < Devise::Mailer before_action :add_image private def add_image images = ['***.png', '***.jpg'] images.each do |img| attachments.inline[img] = File.read("#{Rails.root}/app/assets/images/mailer/" + img) end end endHTMLの編集
[/app/views/users/mailer/confirmation_instructions.html.erb」のファイルを修正する
confirmation_instructions.html.erb<p>Welcome <%= @email %>!</p> <p>会員登録ありがとうございます。</p> <%= image_tag attachments['***.png'].url, alt: "***" %> <%= image_tag attachments['***.jpg'].url, alt: "***" %> <p><%= link_to 'アカウント有効化', confirmation_url(@resource, confirmation_token: @token) %></p>こちらで会員登録した際に画像が挿入されています。
以上。ここまで読んでいただきありがとうございます。
参考
- 投稿日:2021-01-16T19:28:36+09:00
dotenv-rails必要なのか?
現在awsで作成しているアプリケーションをデプロイ中に
dotenv-rails必要あるのかと思ったので投稿・
dotenv-rails
とはRailsで使える環境変数を管理できるgem(dotenv-rails)や.envの導入方法
簡単にいうと自分で変数セットしていろんなところで使えちゃいます。ということなのだが
rails5.2からは
credentials.yml.enc
という物がデフォルトで追加されています。皆さんのconfigフォルダの中にも存在すると思います。これも環境変数指定できいろんなところで使えちゃいます。どっちも同じならどっち使ってもいいじゃん!て思いますよね〜
ただただ変数をセットする
dotenv-rails
とは違いcredentials.yml.enc
は暗号化して環境変数を保持するんです!そしてconfig/master.keyを使って複合して使うという違いがあります。環境変数は見られたくないんだけど〜っていうところに使う物なので暗号化は大切ですね!
もし
dotenv-rails
を使い大事な値を.envで管理していると何かの拍子にフォルダを見られた際にふむふむここねといって.env内見られたら終わりです。
credentials.yml.enc
であれば見られても暗号化されているので「わけワカメ」となるわけですね。おまけ
credentials.yml.enc
はgitに上げてもmaster.keyがないかぎり他の人はどうしようもないのでデプロイの際にcloneで持ってきてmaster.keyをローカルから引っ張ってこれば使えちゃうんですよね。セキュリティー面を考えたらこっちの方が良いのは明らかですねー
ただ
credentials.yml.enc
を使用する時にはRails.application.credentials.セットした環境変数 #dotenv-railsだと ENV['セットした環境変数']長い!! でもVScodeだと何回か打ってると予測してくれるから問題なし
そして環境変数を設定するときも(dockerだと)
docker-compose run -e EDITOR="vim" web rails credentials:editでvim開いて編集という面倒くささはあります。
ちなみにFile encrypted and saved.とでてしまう人は多分vimが入っていないのでinstallしてください
僕の場合だと
Dockerfile #追加 apt-get install vimいやーまだまだ知らないことがたくさんあって面白いな〜
何か間違っていたらご教授お願いします。
では〜⭐️
- 投稿日:2021-01-16T18:25:17+09:00
ActiveRecordでwhere in句を書こうとして詰まったこと
SQLで書くとわかるが、Railsでどのように書くか悩んだので、書いておく
知りたかったこと
SELECT * FROM Tables WHERE (name, task) not in ((yamada, "running"),(yamada, "swimming"));いろいろ悩んだが上手くまとめられなかったので、サブクエリで解決しました〜!
配列で渡すと複数個渡せますし、このようにサブクエリにすると欲しい条件が作れるのかなと思います!期待値通りのクエリが発行Table.where.not(id: (Table.select(:id).where(name: yamada).where(task: ["running", "swimming"])))当初の方針
最初の方針ではwhere句を複数繰り返すことで条件を絞れると思ってましたが、以下のように書いたら"yamada"さんの全てのtaskを弾いてしまいます。実際に発行されるSQLも下に記載しておきます。
ベン図を頭の中に描きながら書いていきました。期待値と違うクエリが発行Table.where.not(name: yamada).where.not(task: ["running", "swimming"])期待値と違うクエリSELECT `tables`.* FROM `tables` WHERE `tables`.`deleted_at` IS NULL AND (`tables`.`name` != "yamada") AND (`tables`.`task` NOT IN ("running", "swimming"))参考文献
- 投稿日:2021-01-16T18:09:56+09:00
[React + TypeScript ] HTMLSelectElementのつもりなのに、Property 'options' does not exist on type 'HTMLElement'.
課題
今日もTypeScriptから怒られた。
something.tsxconst months = document.getElementById('datetime_2i') months ? (months.options[1].selected = true) : nullエラー> Property 'options' does not exist on type 'HTMLElement'.HTMLSelectElementのつもりなんだけどな。
結論
つもりなら書けと言うことらしい。
地味に時間取られる。something.tsxconst months = document.getElementById('datetime_2i') as HTMLSelectElement months ? (months.options[1].selected = true) : nullTypeScript素人故怒られまくる。
エラー解決するたびに只管メモします。参考情報
Property 'selectedOptions','selectedIndex','options' does not exist on type 'HTMLElement'
https://sharepoint.stackexchange.com/questions/283252/property-selectedoptions-selectedindex-options-does-not-exist-on-type-htm
- 投稿日:2021-01-16T17:26:10+09:00
form_with関連でつまずいたことのまとめ
はじめに
Railsチュートリアル(version5.1対応)を1周して、ポートフォリオ作りをする際に、form_withでいくつか詰まったので備忘録として記事を書きます。間違っているところがあればコメントいただけるとありがたいです。
以下発生したエラーごとにまとめていきます。
flashが表示されない
以下のような記事を投稿するフォームを作成
_post_form.html.erb<%= form_with model: @post, url: yield(:form_url), method: yield(:method), local: true, multipart: true do |form| %> ・・・フォームいろいろ <% end %>初め、local: true の設定を行わずに書いていたのですが、投稿成功のflashの表示ができなくなって困っていました。どうやら、form_withはデフォルトではAjaxを用いて通信を行うようで、それによりflashが表示できないようです。(詳しい原理理解はしていません)
ファイルの送信が行えない
これは以下のようにpdfファイルを送信するフォームを作る際に起こりました。
_post_form.html.erb<%= form_with model: @post, url: yield(:form_url), method: yield(:method), local: true, multipart: true do |form| %> ・・・他のフォーム・・・ <%= form.label :file, "pdfファイル", class: "control-label" %> <%= form.file_field :file, class: "form-control-file" %> <% end %>pdfファイルの送信には、carrierwave を導入しました。carrierwaveのセッティングについては別記事にまとめます。今回は、それが終わった後の話です。
フォームが送れないのでググったところ、form_withの引数に、multipart: trueを指定していませんでした。これを指定すると、ファイルの形式も送信できるようになるようです。Rails4以降ではfile_fieldの記述があれば暗黙にmultipart: trueが指定される、と書いていたのですが、なぜか僕はされていませんでした・・・。scopeオプションについて
以下の記事を参照しました。
https://qiita.com/akilax/items/f36b13f377f7e442bc73データをパラメーターとして送る際に strong parameters として送るために指定する値、と理解しました。(正しいのか・・・?)
終わりに
まだ理解が浅いので、今後新しい発見があり次第追記していくつもりです。form_with 奥が深いな・・・。
- 投稿日:2021-01-16T17:16:21+09:00
テーブルが存在するのに、Table doesn't existと言われた話
はじめに
先日、PCの電源を閉じた後、再度dockerを起動し、
docker-compose run wen rails s
と入力すると、以下のようなエラーが出てしまいました。Mysql2::Error: Table 'share_read_development.books' doesn't exist現在でも、主原因は解明できておりません。
本記事では、僕が解決に向けて試したことを記載していきます。エラーが起きた主原因は不明でしたが、エラーの解決は済んでおり開発自体は進んでおります。
もし同じようなエラーに苦しんでいる方は、参考にしてみてください。また原因がわかる方がいらっしゃいましたら、コメントで教えていただけると幸いです。
開発環境
Ruby 2.72
Rails 6.0.2.3
MySQL 5.7
Docker/docker-compose発生したエラー
冒頭でも簡単に記載しましたが、以下のようなエラーが出ました。
booksテーブルがないと言われています。rails aborted! ActiveRecord::StatementInvalid: Mysql2::Error: Table 'share_read_development.books' doesn't exist /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query' /usr/local/bundle/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:201:in `block (2 levels) in execute' /usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads' /usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares' # 中略 Caused by: Mysql2::Error: Table 'share_read_development.books' doesn't exist /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `handle_interrupt' /usr/local/bundle/gems/mysql2-0.5.3/lib/mysql2/client.rb:130:in `query' # 中略 /usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:291:in `load_dependency' /usr/local/bundle/gems/activesupport-6.0.3.4/lib/active_support/dependencies.rb:324:in `require' bin/rails:4:in `<main>' Tasks: TOP => db:schema:dump (See full trace by running task with --trace)試したこと
①マイグレーションの実行状況の確認
まず、マイグレーションの実行状況を確認しました。$ docker-compose run web rails db:migrate:status Status Migration ID Migration Name -------------------------------------------------- up 20201207135139 Create users up 20201213135207 Create reviews up 20201218052640 Create books up 20201218075413 Add bookgenreid to books up 20201220063200 Add book to reviews up 20201222080803 Create relationships up 20201222131717 Create favorites up 20201222233733 Create comments up 20201224140712 Create bookcases up 20201225105949 Create notifications up 20201226102230 Add status to review up 20201230042031 Add caption to books全てのマイグレーションファイルが実行されていることがわかりました。
②データベースの確認
次にmysqlに接続し、デーベースのテーブルを確認しました。$ docker-compose run web rails db > show tables;そうすると、以下のように表示されました。
booksテーブルは存在している?+----------------------------------+ | Tables_in_share_read_development | +----------------------------------+ | ar_internal_metadata | | bookcases | | books | | comments | | favorites | | notifications | | relationships | | reviews | | schema_migrations | | users | +----------------------------------+しかし、以下のコマンドでは、booksテーブルがないと言われてしまいます。
> select * from books;他のテーブルのデータは取得できます。
> select * from bookcases; +----+------+---------------+---------+----------------------------+----------------------------+ | id | read | book_id | user_id | created_at | updated_at | +----+------+---------------+---------+----------------------------+----------------------------+ | 1 | 0 | 9784296108008 | 1 | 2020-12-28 01:18:40.540283 | 2020-12-28 01:18:40.540283 | | 3 | 0 | 9784478820094 | 3 | 2020-12-28 12:39:00.697316 | 2020-12-28 12:39:00.697316 | | 37 | 0 | 9784478820094 | 1 | 2020-12-29 08:16:25.944979 | 2020-12-29 08:16:25.944979 | | 39 | 0 | 9784804614151 | 1 | 2020-12-29 08:26:56.615557 | 2020-12-29 08:26:56.615557 | | 41 | 0 | 9784907095536 | 1 | 2020-12-29 08:27:01.301378 | 2020-12-29 08:27:01.301378 | | 42 | 0 | 9784908925658 | 1 | 2020-12-29 08:39:11.191829 | 2020-12-29 08:39:11.191829 | | 45 | 0 | 9784284204705 | 1 | 2020-12-30 04:10:08.090943 | 2020-12-30 04:10:08.090943 | +----+------+---------------+---------+----------------------------+----------------------------+公式ドキュメントを調べても、自身で試したことしか記載していませんでした。
エラー Table 'xxx' doesn't exist または Can't find file: 'xxx' (errno: 2) が発生する場合、xxx という名前のカレントデータベースにテーブルがないことを示しています。
SHOW TABLES を使用して、カレントデータベースにあるテーブルを確認できます。【URL】
http://download.nust.na/pub6/mysql/doc/refman/4.1/ja/cannot-find-table.html③データベースの作り直し
あまり気が進みませんでしたが、データベースを作り直すことにしました。$ docker-compose run web rails db:reset $ docker-compose run web rails db:create $ docker-compose run web rails db:migrateこれでエラーが解消することができました!
個人開発なので、データベースを削除するという方法で済みましたが、実際の現場ではこの方法は推奨されないと思います。
もし、今回のエラーの原因等がわかる方がいらっしゃいましたらコメントにて教えていただけると幸いです。
- 投稿日:2021-01-16T16:10:32+09:00
記事を投稿する
備忘録的に使用しています。
間違い等々あればご指摘ください!1.コントローラーで定義
newとcreateの定義
newは新規作成するだけ、定義なし
createは「どんな内容」を投稿するか
テーブル名.create(引数)2.投稿フォームのviewの作成
new.html.erb : 投稿するときに出る画面
・フォームタグで作成
form_tag ('/テーブル名' method: :post) docreate.html.erb :投稿後に切り替わった画面
- 投稿日:2021-01-16T15:54:42+09:00
heroku と vercel にお手軽デプロイ
heroku の cli を入れる
ゴニョゴニョ調べてください?
rails api のデプロイ heroku
できてる rails app に行く
cd hogehoge-apiheroku app を作る
heroku create -a hogehoge-apiheroku の
Deploy
タブ押して github との接続とかして、Deploy Branch
ボタンを押す。
終わり??next.js のデプロイ vercel
vercel のマイページ行く
New Project
を押す
github とつなぐ
Deploy
を押す
終わり??かんたんすぎる!!!!!!!!!!!!!!!
あとはそれぞれのダッシュボードでドメインの設定とかをポチポチするだけです
- 投稿日:2021-01-16T14:50:10+09:00
部分テンプレートを使用する(保守性の高いコードを書く)
前書き
ある程度ポートフォリオが完成してきたところでコードの手直しを行なっていくことにしました。
実際の業務では保守性の高いコードが求められているからです。具体的には同じコードは一つにまとめておくことによって手直しするときに複数直さなくても済むように改善していきます。
書き方を忘れないように備忘録として残しておきます。部分テンプレートの使用
ヘッダーは他のページでも繰り返し使用するので部分テンプレートとしてまとめていきます。
部分テンプレートとは、ビューファイルで繰り返し使用するコードを切り出し、再利用する仕組みのことをいいます。
部分テンプレートとして切り出すときに作成するファイルは命名規則として、アンダースコアを先頭に記述します。
今回の場合、_header.html.erbとなります。
app/views/shared/header.html.erbディレクトリに作成していきます。renderメソッド
renderメソッドは、部分テンプレートを呼び出す際に利用するメソッドのことです。
<%= render "ディレクトリの指定" %>と記述します。
例えばindex.html.erbやshow.html.erbでもヘッダーのコードを使いたい時にrenderメソッドで使い回すことができます。index.html.erb<%= render "shared/header" %> <div id="home-index" class="contents row"> <h2 class="page-title">Find your favorite!</h2> <p class="page-p">歌いたかったあの曲との出会い提供するMY KARAOKE。 </p> <p class="page-p">このページではみんなが歌いたい曲の情報が満載です。 みんなの曲を見てレパートリーを増やしましょう。 </p> 省略_header.html.erb<header class='top-page-header wrapper'> <%= link_to 'MY KARAOKE', root_path, class: "title" %> <nav> <ul class="main-nav"> <% if user_signed_in?%> <li><%= link_to current_user.nickname, new_user_session_path, class: "user-nickname" %></li> <li><%= link_to 'ログアウト', destroy_user_session_path, method: :delete, class: "logout" %></li> <% else %> <li><%= link_to'ログイン', new_user_session_path, class: "login" %></li> <li><%= link_to '新規登録', new_user_registration_path, class: "sign-up" %></li> <li><%= link_to 'ゲストログイン', users_guest_sign_in_path, method: :post %></li> <% end %> </ul> </nav> </header>一行目の<%= render "shared/header" %>よって_header.html.erbのコードを使用することができます。
部分テンプレートを作成したことによってindex以外のページでも同じように使い回すことができます。show.html.erb<%= render "shared/header" %> <div class="main"> <div class="song-show"> <table class="detail-table"> <tbody> <tr> <th class="show-detail-value">投稿者</th> <td class="show-detail-song"> <%= link_to user_path(@song.user_id) do %> <%= @song.user.nickname %> <% end %> </td> </tr> 省略今回はわかりやすいようにヘッダーの例を出しましたがもちろんそれ以外も部分テンプレートが使える場面があります。
例えばnewとeditは新規投稿する際にフォームなどはほぼ同じ記述になるので(少なくとも僕の場合は)使えたりします保守性の観点からまとめてあげるほうが後々楽になるのでやっておくほうがいいと思います。後書き
とりあえず簡単な部分テンプレートいついてまとめました。 localsオプションを使った部分テンプレートの記事を次回書いてみようかと思っています。
- 投稿日:2021-01-16T13:55:36+09:00
VScodeのスニペット機能を活用しよう ~ もう<%=%>はいちいち打ちたくない ~
概要
railsの開発をしていると、結構書くことになる「<%= %>」や「<% %>」。
いちいち打つのは結構めんどくさい。
なので、VScodeのスニペット機能を使って簡単にこれらのめんどくさいコードを打つ時間の短縮をしてみよう!
もちろん、他の言語でもOK!導入の仕方
VScodeの左下の歯車マークをクリック
Command paletteを開く
snippetsと打って、省略したいコードの言語の拡張子を選択
スニペットを記述しよう
自由にスニペットは作れるのですが、
と書き方は、以下のように
はじめの””の中には、当該スニペットの端的な内容
prefixの後には、スニペットを出力するためのトリガー
bodyの後には、実際出力したいコードの内容
descriptionの後には、スニペットの説明
を記述します!ruby{ // Place your snippets for erb here. Each snippet is defined under a snippet name and has a prefix, body and // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the // same ids are connected. // Example: "write <%=%> more easier": { "prefix": "pa", "body": [ "<%= $0 %>" ], "description": "Log output to console" } }また、$0をかけば、カーソルの位置を指定できます。
上の例のようにかけば、<%= %>における=と%の間にカーソルが合います。
同様に、$1や$2をかけば、改行を挿入できます。また、以下のように記述すれば複数のスニペットを作成できます。
ruby{ // Place your snippets for erb here. Each snippet is defined under a snippet name and has a prefix, body and // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the // same ids are connected. // Example: "write <%=%> more easier": { "prefix": "pa", "body": [ "<%= $0 %>" ], "description": "Log output to console" }, "write <%%>": { "prefix": "ni", "body": [ "<%%>", ], "description": "Log output to console" } }終わり
- 投稿日:2021-01-16T12:48:09+09:00
Docker ComposeでRails環境を構築
初学者の方向けに発信されているきよとのプログラミング大学のチャンネルで、Docker Composeを使ったRails環境構築の動画を見つけ、これが非常に分かりやすかったので、備忘録として記事にまとめたいと思います。
DockerでRails環境をつくりたいという方はこの動画を見ればOKだと思います。
https://youtu.be/ltDdZAJli8cDocker Composeとは
複数のアプリケーションをまとめて操作できるツール。例えばRailsでアプリケーションを開発する際、最低限Webサーバーとデータベースサーバーが必要になるが、通常それぞれのサーバーを構築し、接続するなどの操作が必要となる。docker-composeではコマンド一発でそれらを立ち上げて接続することができるため、非常に楽に開発環境を構築することができる。
全体の流れ
- Docker関連のファイルを用意
- 初期設定
- 起動
- よく使うコマンド
Docker関連のファイルを用意
① Dockerfile
ここにrailsのイメージを作成する記述を行う。
Dockerfile# ベースイメージを指定 FROM ruby:2.7 # nodejsとyarnをインストールするため、JavaScript関連のライブラリをインストール RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ # nodejsとyarnをインストール && apt-get update -qq \ && apt-get install -y nodejs yarn # 作業ディレクトリを指定 WORKDIR /app COPY ./src /app # Ruby関連のライブラリ(gem)のインストール RUN bundle config --local set path 'vendor/bundle' \ && bundle install※ APIモードで開発をする場合、nodejsとyarnは不要
② Gemfile
次にGemfileを用意します。
Gemfilesource 'https://rubygems.org' gem 'rails', '~> 6.1.0'上記のように、
rails
のライブラリが入った状態でrails new
を実行すると、railsのファイルの雛形を一斉に作ることができる。その際、Gemfileが新しく作成され、それと置き換わる形となる。③ docker-compose.yml
最後にdocker-compose.ymlを用意します。
docker-compose.ymlersion: '3' services: db: image: mysql:8.0 # mysql8.0から認証形式が変更になっていて、それを5系の認証形式に戻す設定。これをしないとエラーになる command: --default-authentication-plugin=mysql_native_password volumes: - ./src/db/mysql-data:/var/lib/mysql # 環境変数の設定 # MySQLはパスワードを設定しないとエラーになる environment: MYSQL_ROOT_PASSWORD: password web: build: . # 標準入出力を有効にする設定 # これをしないとデバックができない tty: true stdin_open: true command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - ./src:/app # gemを入れた際に、buildし直さなくても良くする設定 - bundle:/usr/local/bundle ports: - "3000:3000" # railsからMySQLへ接続する際、接続情報としてdbサービスのIPアドレスを指定する必要がある。その接続先のIPアドレスをdbで接続できるようにする設定 depends_on: - db volumes: bundle: driver: local開発をしていると、
A server is already running. Check /app/tmp/pids/server.pid.
のエラーでハマることがある。これは、サーバーが実行中か否かをserver.pidの有無で判断しており、何らかの理由でサーバーが実行していないがserver.pidファイルが残った状態となったときに起こる。これを防ぐため、起動時にはserver.pidの削除を行う。command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"初期設定
ファイルが用意できたらrails newコマンドを実行する。
$ docker-compose run web rails new . --force --database=mysqlGemfileが変更されたため、イメージの再ビルド
$ docker-compose buildconfig/database.ymlを参照し、データベースへの接続先情報を修正する。
database.ymldefault: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root # docker-compose.ymlで設定したパスワードを入力 password: password # docker-compose.ymlのdepends_onで設定した値を入力 host: db # 以下略起動
$ docker-compose up -dブラウザでlocalhost:3000へアクセスし、下画面が表示されれば成功!
よく使うコマンド
- イメージのビルド
$ docker-compose build
- コンテナの作成と起動
$ docker-compose up -d
- コンテナを停止、削除
$ docker-compose down
- コンテナの一覧を表示
$ docker-compose ps
- ログを表示
docker-compose logs
- コンテナを作成してコマンドを実行
$ docker-compose run <サービス> <コマンド>
- 起動中のコンテナにコマンド実行
$ docker-compose exec <サービス> <コマンド>
- 投稿日:2021-01-16T11:53:01+09:00
RailsにjQueryを導入する方法
jQueryの導入
gemファイルの確認
Gemfileの中に、
gem 'jquery-rails'がない場合は、自分でそのファイルの一番下に記入して、ターミナルで
bundle installを実行します。
application.jsの中身変更
//= require jquery //= require rails-ujs //= require activestorage //= require_tree .上記のように変更します。
順番が重要みたいです。作動するか確認
適当にビューファイルを選択し、その中に
<h1>テスト</h1> <script type="text/javascript"> $("h1").css("color", "red"); </script>のように記述すると、jQueryが効いてh1タグの文字が赤くなると思います。
※私の場合、最初jQueryが作動しなかったので、一旦サーバーを再起動したら、正常に動きました。
別のファイルにjQueryを記述する
コードが増えてくると、このままだとビューファイルの中が煩雑になってくるので、test.jsのようなファイルを別に作成します。
作成する場所は「app/assets/javascripts」の配下です。jQueryの様式に則って、
$(function() { $("h1").css("color", "green"); });のようにコードを書きます。
先ほどのビューファイルに書いたは、削除します。
これで、再度ブラウザで確認し、h1タグの文字が赤くなっていればjQueryは無事に起動しています。
参考記事
https://web-camp.io/magazine/archives/17690
こちらの記事がとても分かりやすかったです。
- 投稿日:2021-01-16T11:33:06+09:00
Railsアプリにransackを導入したけどあたふたした話。
ポートフォリオ用のアプリにransackを使って検索機能を実装しようとした際にちょっと詰まったので
備忘録を残しておきます。やりたいこと
検索文字列を含んだ投稿を検索する機能を実装したい。
ひとまずransackをインストール
Gemfilegem 'ransack'$ bundle installコントローラーについて
posts_controller.rbclass PostsController < ApplicationController before_action :set_q, only: [:index, :search] def search @results = @q.result end private def set_q @q = Post.ransack(params[:q]) end endルーティングについて
routesresources :posts do collection do get :search end endビューについて
posts/index.html.erb<%= search_form_for @q, url: search_posts_path do |f|%> <%= f.text_field :body_cont, placeholder: "検索"%> <%= f.submit "検索"%> <% end%>posts/search.html.erbお好みにカスタマイズ
結論
色々な記事などに<%= f.search_field :body_cont %>
と記されていたのですが、これだとうまく行かなかったです。
ヤケクソで<%= f.text_field :body_cont %>にすると
すんなり行きましたー!
- 投稿日:2021-01-16T09:20:21+09:00
エラーメッセージの日本語化
はじめに
オリアプ制作の中で、エラーメッセージの日本語化を行ったので、忘れないよう載せておこうと思います。
ユーザーがきちんとフォーム入力を出来ていない際に、エラーメッセージが英語ではどこに不備があるかが分かりづらいのでは?と感じたため、日本語化を実装しようと思いました。事前状況:ユーザー登録等にはdeviseを導入している / 単体エラーコードは記述済み
今回の流れとして、localeファイル内に日本語変換用yamlファイルを作成する事で英語を翻訳していく。
(localeファイル:多言語化用の言語ファイル)1.gemの導入
1.エラーメッセージを日本語化するために『rails-i18n』というgemをGemfileに記述しbundle installする。
これは以下のリンク先に記述してある語句を日本語にしてくれるもの。
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.ymlGemfilegem 'rails-i18n'2.config/application.rb に config.i18n.default_locale = :ja を記述し、言語の設定を行う
config/appllication.rbmodule IdeaApp class Application < Rails::Application # 中略 config.i18n.default_locale = :ja # 中略 end end2.devise関連の日本語化
ユーザー登録等にはdeviseを導入しているため、それに関連するものの日本語化を行う。
1.config/locales に devise.ja.yml を作成する。
→config / locales / devise.ja.yml2.devise.ja.yml内に以下のリンク先に記述してあるコードをペーストする。
ペーストすることで、記述してある語句を日本語にする。
https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml3.指定した単語の日本語化
ここまでの実装で、rails-i18nやdevise.ja.ymlに記述してある語句に関しては日本語化出来ているが、そのほかの語句は以下の画像のように日本語化出来ていない。
そのため、こちらで語句(NicknameやTitle、Category)などを指定し、日本語に変換する必要がある。
1.config/locales に ja.yml を作成する
→config / locales / ja.yml2. ja.yml に以下のように変換したい語句の変換前・変換後を記述する
config/locales/ja.ymlja: activerecord: attributes: user: #Userモデル nickname: ニックネーム phone_number: 電話番号 first_name: 名前 last_name: 名字 first_name_kana: 名前カナ last_name_kana: 名字カナ idea: #Ideaモデル title: アイデア名 idea: アイデアの内容 price: 価格 category_id: カテゴリー errors: messages: other_than: 「--」以外を選択してください4.日本語に変換後
5.補足:エラーコード修正
すでに単体テストコードを記述している場合は、期待するエラーメッセージも日本語に変換されるため、書き換えが必要になる。
例としてNicknameのエラーコードを記載する。spec/models/user_spec.rb 書き換え前# 中略 context '新規登録がうまくいかないとき' do it 'nicknameが空だと登録できない' do @user.nickname = '' @user.valid? expect(@user.errors.full_messages).to include("Nickname can't be blank") end end # 中略spec/models/user_spec.rb 書き換え後# 中略 context '新規登録がうまくいかないとき' do it 'nicknameが空だと登録できない' do @user.nickname = '' @user.valid? expect(@user.errors.full_messages).to include("ニックネームを入力してください") end end # 中略最後に
英語が苦手な人にもエラーメッセージが読めるように実装することが出来ました。
今後も誰にでも使いやすいアプリを制作できるように意識していきたいです。
- 投稿日:2021-01-16T01:30:43+09:00
【3行で説明】プログラミングスクールの技術記事を検索結果に表示させない方法
※単純に初歩的すぎる記事を見る必要がなくなった時に使う方法です。他意はありません。
1.Chromeでこの拡張機能(uBlacklist)を入れる。
2.表示してほしくないサイトに行く、または調べる
3.拡張機能のボタン(ブラウザ右上のパズルのようなマーク)から選択して、ブロックを押す。
- 投稿日:2021-01-16T00:13:01+09:00
[Rails]"kaminari"の使い方について
はじめに
"kaminari"の実装をやったので忘れないように記していきます。
「kaminari」
ページネーションを実装するためのrubyのgemの一つです。
何かの一覧ページを表示した時に、たくさんある場合見やすいようにページを数字で分割してくれ、最初や最後のページに飛べるボタンが実装できたりします。
実装
インストール
まずはgemをインストールします。
日本語表記にするので一緒に「i18n」もインストールします。「i18n」は以前学習していましたのでいちお貼っておきます。
Gemfilegem 'kaminari' gem 'rails-i18n'インストール!
bundle install
コントローラ
controller.rbdef index @advises = Advise.page(params[:page]) endビューファイル
view.html.erb<div class="advise-lists"> <% @advises.each do |advise| %> <ul class="advise-text"> <li><%= link_to advise.title, advise_path(advise), class: "advise2_link" %></li> </ul> <% end %> <!--↑ 一覧表示の部分--> </div> <!--↓ ページネーション実装部分--> <%= paginate @advises %>「kaminari」の設定ファイルを作成
rails g kaminari:config
「kaminari_config」ファイルが作成されます。
お好みで変更していきます。こちらでは「default_per_page」を1ページあたり3行とわざと小さく設定しています。
config/initializers/kaminari_config.rb# frozen_string_literal: true Kaminari.configure do |config| config.default_per_page = 3 # config.max_per_page = nil # config.window = 4 # config.outer_window = 0 # config.left = 0 # config.right = 0 # config.page_method_name = :page # config.param_name = :page # config.max_pages = nil # config.params_on_first_page = false endたくさん項目がありますが
こちらでは
フリーランスLIFE!:【Rails】でページネーションをgemで実装!TECH SCORE BLOG:Railsライブラリ紹介: ページングを行う「kaminari」
以下のように説明されています。
default_per_page
デフォルトのページあたりの表示件数(デフォルトは 25)。max_per_page
ページあたりの表示件数の最大(デフォルトは nil、つまり無制限)。window
表示中のページの左右何ページ分のリンクを表示するかを指定します(デフォルトは 4)。上記画像はデフォルトの 4 で、11 ページを表示しているところです。11 の左右それぞれ 4 ページ分のリンクが生成されています。outer_window
先頭ページ、及び最終ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。left、right が指定された場合は、そちらの値が優先されます。left
先頭ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。上記画像は 3 を指定した場合です。right
最終ページから何ページ分のリンクを表示するかを指定します(デフォルトは 0)。上記画像は 2 を指定した場合です。page_method_name
モデルに追加されるページ番号を指定するスコープの名前(デフォルトは page)。param_name
ページ番号を渡すために使用するリクエストパラメータの名前(デフォルトは page)。引用: Railsライブラリ紹介: ページングを行う「kaminari」
ロケールの設定
ロケールファイルのロードパスを設定します。
デフォルトロケールを「日本語( ja )」にセットします。config/application.rbconfig.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", "*.{ry,yml}").to_s] config.i18n.default_locale = :javiewディレクトリを作り、その下にファイルを作ります。
locales/views/pagenate.ja.ymlja: views: pagination: first: "先頭" last: "最後" previous: "前へ" next: "次へ" truncate: "..."そうすると英語表記から日本語表記に代わって表示され、ページネーションが実装されます。
さらにカスタマイズをしたい場合は
rails g kaminari:views default
を入力すると
viewにこれらが作成されます。これらのファイルを編集すれば、ページネートのビューを変更することができます。
(_gap.html.erbはページが省略される"..."の部分、
_page.html.erbはページ番号の部分、
_paginator.html.erbは全体の構成定義)まとめ
装着するの自体はそんなに難しくはないですが、カスタマイズの仕方をもう少し触って勉強していきたいと思います。
装飾とカスタマイズの部分をまた近々やっていきたいと思います。
参考
kikawaka:【Rails】kaminariの使い方をマスターしよう!
設定項目を確認するには・・
RAILS GUIDES:Configuring Rails Applications
装飾の参考