- 投稿日:2020-10-24T23:49:20+09:00
[Ruby] each_with_index と each.with_indexの違いを考えた
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
2つの違いを区別するためにまとめてみました。each_with_index
- each_with_indexと2つの値をブロック変数に渡すことで、配列の要素の数だけ繰り返し処理とその要素が何番目のものか表すことができます。
fruits = ["apple", "banana", "peach"] fruits.each_with_index do |fruit, index| puts "#{index}番目のフルーツは#{fruit}です。" end結果
ただ、このままだと「0番目のフルーツはappleです。」となってしまいますね。
0番目のフルーツはappleです。 1番目のフルーツはbananaです。 2番目のフルーツはpeachです。each.with_index
- indexの引数に1を入れました。
- すると、要素に割り振られる番号が1からスタートになります。
fruits.each.with_index(1) do |fruit, index| puts "#{index}番目のフルーツは#{fruit}です。" end結果
この通り、きれいに1から順番が始まっていますね。
1番目のフルーツはappleです。 2番目のフルーツはbananaです。 3番目のフルーツはpeachです。
- 投稿日:2020-10-24T23:43:12+09:00
データベースに登録するときにエラーメッセージを表示させたい
はじめに
テストコードを書いていて、エラーメッセージを表示させるようにしたときに、わからなかったことなので、記録として残しておく。
エラーメッセージの表示方法
viewディレクトリに
_error_messages.html.erb<% if model.errors.any? %> <div id="error_explanation" class="alert alert-danger"> <ul> <% model.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %>を作成し、
renderメソッド
で呼び出すようにする。
1行目のmodelは、今回データベースに何かを登録する場面を想定しているため。呼び出す側のコード
<%= render 'error_messages', model: f.object %>ファイルの位置によって、
shared/error_messages
のように指定してあげる必要がある。
- 投稿日:2020-10-24T23:33:19+09:00
Dockerを組み込むために参考にした記事
参考にした記事
DockerをMacにインストールする
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81はじめてのDocker 導入から開発の流れまで
https://qiita.com/m-dove/items/173d08a5d8d910e10283最初はわからなさすぎたのでYouTubeなども見ましたー。
もう環境構築で悩まない!Dockerを使ってRails環境構築!
https://www.youtube.com/watch?v=BZS8AHF3TTo&t=503s
- 投稿日:2020-10-24T23:08:17+09:00
即時に更新されるチャット機能(Action Cableの実装)
即時に更新されるチャットアプリ
- Action Cableを用いた、リアルタイムチャットアプリを作成する
まとめてコードずらりします⬇︎
ターミナル% cd projects % rails _6.0.0_ new mini_talk_app -d mysql % cd mini_talk_app % rails db:createターミナル% rails g controller messages new % rails g model message text:text % rails db:migrateapp/config/routes.rbRails.application.routes.draw do root 'messages#new' resources :messages, only: [:create] endapp/controllers/messages_controller.rbclass MessagesController < ApplicationController def new @messages = Message.all @message = Message.new end def create @message = Message.new(text: params[:message][:text]) end endapp/views/messages/new.html.erb<h3>mini_talk_app</h3> <%= form_with model: @message do |f| %> <%= f.text_field :text %> <%= f.submit '送信' %> <% end %> <div id='messages'> <% @messages.reverse_each do |message| %> <p><%= message.text %></p> <% end %> </div>この時点で下記のようになっているはず
Action Cableの実装(先ほどの続き)
ターミナル% rails g channel messageapp/channel/message_channel.rbclass MessageChannel < ApplicationCable::Channel def subscribed stream_from "message_channel" end def unsubscribed # Any cleanup needed when channel is unsubscribed end endapp/controller/messages_controller.rbclass MessagesController < ApplicationController def new @messages = Message.all @message = Message.new end def create @message = Message.new(text: params[:message][:text]) if @message.save ActionCable.server.broadcast 'message_channel', content: @message end end endapp/javascript/channels/message_channel.jsimport consumer from "./consumer" consumer.subscriptions.create("MessageChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { const html = `<p>${data.content.text}</p>`; const messages = document.getElementById('messages'); const newMessage = document.getElementById('message_text'); messages.insertAdjacentHTML('afterbegin', html); newMessage.value=''; } });現場からは以上です!
- 投稿日:2020-10-24T20:56:28+09:00
[chown]ファイルやディレクトリの所有者を変更する方法
chownコマンドとは?
ファイルやディレクトリのユーザーやグループの所有権を変更するためのコマンド。
$ chown [オプション] ユーザーorグループ ファイルorディレクトリ使い方
1.対象のファイルのユーザー・グループの所有権を確認する。
※実行結果からユーザー所有権は「sample」グループ所有権「sample」であることがわかります。$ ls -l #=> -rw-rw-r— 1 sample sample 47 5月 21 08:42 test1.htmle.erb2.ユーザー所有権を変更するには以下のように実行します。
$ chown root test1.htmle.erb $ ls -l #=> -rw-rw-r— 1 root samurai 47 5月 21 08:42 test1.htmle.erb3.グループの所有権も変更する場合には引数にセミコロン「:」をはさんで「ユーザー:グループ」とする。
$ chown root:root test1.htmle.erb $ ls -l #=> -rw-rw-r— 1 root root 47 5月 21 08:42 test1.htmle.erbオプション一覧
オプション 説明 -c 所有者情報を変更された場合に詳細を表示する -f エラーメッセージを表示しない -h シンボリックリンクの所有権も変更する -R ディレクトリ内の所有権も変更する -v 所有者変更情報の詳細を表示する(変更されなかった場合も表示)
- 投稿日:2020-10-24T20:31:01+09:00
[Linux]かんたんに解説!権限確認と変更方法
パーミッションの確認方法
Linuxコマンドでカレントディレクトリ内のファイルやディレクトリの情報を確認する。
$ls -l #=> -rw-r--r-- 1 user group 9 1月 1 00:00 hoge.html.erb drwxr-xr-x 6 user group 20480 1月 1 00:00 ダウンロードパーミッションの読み方
最初の1文字目はファイル種別を表す。
2〜4文字目はファイルの所有者に対する権限を表す。
5〜7文字目はファイルの所有グループに対する権限を表す。
8〜10文字目はその他に対する権限を表す。権限の区分(設定する範囲)
種別 意味 - ファイル d ディレクトリ l シンボリックリンク 権限の基本種類
読み込み権限 書き込み権限 実行権限 r w x 権限の範囲
数値 権限 内容 0 --- 権限無し 1 --x 実行可 2 -w- 書込可 3 -wx 書込、実行可 4 r-- 読込可 5 r-w 読込、実行可 6 rw- 読込、書込可 7 rwx 読込、書込、実行可 -例-
-rw-r--r--
↓
ファイル種別=ファイル
所有者=読み取りと書き込み権限有り
所有グループ=読み取り権限有り
その他=読み取り権限有りアクセス権限の変更方法
$ chmod モード 対象ファイル名 $ chmod 764 hoge.html.erbコマンドのオプション
引数 内容 -v コマンド実行結果を表示 -c 変更があった場合のみ、実行結果を表示 -R 再帰的に変更
- 投稿日:2020-10-24T20:19:49+09:00
Rails学習 1日目その2
Ruby on Rails5速習実践ガイド chapter2
2-6-1-1 Railsアプリケーションを新規作成する
$ rails new scaffold_app -d postgresqlrails new:Railsの新規ファイル作成
scaffold_app:ファイル名
-d postgresql:SQLの指定(-dはpostgreSQL用ですよという意味)2-6-1-2 ユーザー管理機能のひな形を作る
$ bin/rails generate scaffold user name:string address:string age:integerbin/rails:
scaffold:アプリを作る上での作業をまとめて簡単にしてくれるツール
user:モデル名(userモデル)
name:string address:string age:integer:3つの情報をテーブルに入れテーブルを作成。Column YAMLの基本
YAMLは構造化されたデータを表現するためのフォーマット。
animal: &animal cat: 'ネコ' dog: 'イヌ' animal_shop_1: <<: *animal hamster: 'ハムスター' animal_shop_2: <<: *animal parrot: 'オウム'animalを&animalとしておく
つまり&animal= cat: 'ネコ' dog: 'イヌ'となるanimal_shop_1は
<<: *animal
hamster: 'ハムスター'つまり
&animalとhamster: 'ハムスター'
cat: 'ネコ' dog: 'イヌ' hamster: 'ハムスター'となる
- 投稿日:2020-10-24T20:10:16+09:00
テストコードで「basic認証が通らないエラー」を対応
エラー時の状況
某フリマサイトのコピーアプリを実装したので、練習としてコントローラーの単体テストコードを記述していたところ、実行時にターミナル上で下記エラーが発生しました。
ターミナルbundle exec rspec spec/requests/items_spec.rb ~中略~ 1) ItemsController GET #index indexアクションにリクエストすると正常にレスポンスが返ってくる Failure/Error: expect(response.status).to eq 200 expected: 200 got: 401 (compared using ==) # ./spec/requests/items_spec.rb:20:in `block (3 levels) in <top (required)>' ~中略~開発環境
Ruby 2.6.5
Rails 6.0.3.3
MySQL
Visual Studio Code
(Caprybara,Rspec,GoogleChrome)考察・検証
root_pathへのアクセス時にHTTPステータスが401になっている(アクセスできていない)、というエラーな模様。
本アプリケーションはbasic認証を導入しており、それがが関係しているのではと予想しました。basic認証とは
HTTP通信の規格に備え付けられているユーザー認証の仕組みのことで、Webサイトにアクセス制限をかけることのできる簡易的な方法の一つです。
サーバーとの通信が可能なユーザーとパスワードをあらかじめ設定しておき、それに一致したユーザーのみが、Webアプリケーションを利用できるようにします。【サンプル画像】
上記エラー文とbasic認証で調べた所、やはりテスト時にbasic認証が通らない事例が見受けられました。
参考記事(記事末に掲載)を元に、テスト時のリクエストにbasic認証のユーザー名とパスワードをどうにか渡せないかと試してみました。結果
メンターさんを交えて格闘すること約2時間…
参考記事を元に様々な方法を試みるもエラーは解決せず。
そして、メンターさんが調べたところ…
「2020年現在、テスト時のbasic認証は推奨されていない」とのことでした。
なんてこった…!〜出来ぬなら、やらぬ〜
エラー解決の方針を「テスト時にbasic認証を通す」から、
「本番環境以外(テスト時)はbasic認証をしない」へ変更。application_controller.rbclass ApplicationController < ActionController::Base before_action :basic_auth if Rails.env.production? # テスト時はbasic認証を行わないように分岐 private def basic_auth authenticate_or_request_with_http_basic do |username, password| username == 'username' && password == 'password' end end end※usernameとpasswordは、実際は環境変数で設定しています。
before_actionにif Rails.env.production?を追記して、本番環境でのみ適用するようにしました。
お陰で、テスト時はbasic認証せずそのままトップページへアクセスし、テストを実行できるようになりました!感想
まだまだ初学者なこともあり、エラーに直面すると問題箇所を真正面から解決しようとしがちです。
今回のように、エラーを避ける、「やらずに済む」方法が無いかと多方面から考えることも重要だと実感しました。本記事が初投稿でした。少しでも参考になれば嬉しく思います。
最後まで閲覧いただき、誠にありがとうございました。参考記事
ベーシック認証(Basic認証)とは?設定方法と注意点・エラーになる原因を解説
Rails×Basic認証×Rspecでつまづいた
RSpec3でBASIC認証がかかったアクションをテストする
Rails/Rspecテストをhttp基本認証で渡す
Basic認証を交えたテストコードの書き方
- 投稿日:2020-10-24T20:10:16+09:00
テストコードで「basic認証が通らないエラー」が出る場合の対応
エラー時の状況
某フリマサイトのコピーアプリを実装したので、練習としてコントローラーの単体テストコードを記述していたところ、実行時にターミナル上で下記エラーが発生しました。
ターミナルbundle exec rspec spec/requests/items_spec.rb ~中略~ 1) ItemsController GET #index indexアクションにリクエストすると正常にレスポンスが返ってくる Failure/Error: expect(response.status).to eq 200 expected: 200 got: 401 (compared using ==) # ./spec/requests/items_spec.rb:20:in `block (3 levels) in <top (required)>' ~中略~開発環境
Ruby 2.6.5
Rails 6.0.3.3
MySQL
Visual Studio Code
(Caprybara,Rspec,GoogleChrome)考察・検証
root_pathへのアクセス時にHTTPステータスが401になっている(アクセスできていない)、というエラーな模様。
本アプリケーションはbasic認証を導入しており、それがが関係しているのではと予想しました。basic認証とは
HTTP通信の規格に備え付けられているユーザー認証の仕組みのことで、Webサイトにアクセス制限をかけることのできる簡易的な方法の一つです。
サーバーとの通信が可能なユーザーとパスワードをあらかじめ設定しておき、それに一致したユーザーのみが、Webアプリケーションを利用できるようにします。【サンプル画像】
上記エラー文とbasic認証で調べた所、やはりテスト時にbasic認証が通らない事例が見受けられました。
参考記事(記事末に掲載)を元に、テスト時のリクエストにbasic認証のユーザー名とパスワードをどうにか渡せないかと試してみました。結果
メンターさんを交えて格闘すること約2時間…
参考記事を元に様々な方法を試みるもエラーは解決せず。
そして、メンターさんが調べたところ…
「2020年現在、テスト時のbasic認証は推奨されていない」とのことでした。
なんてこった…!〜出来ぬなら、やらぬ〜
エラー解決の方針を「テスト時にbasic認証を通す」から、
「本番環境以外(テスト時)はbasic認証をしない」へ変更。application_controller.rbclass ApplicationController < ActionController::Base before_action :basic_auth if Rails.env.production? # テスト時はbasic認証を行わないように分岐 private def basic_auth authenticate_or_request_with_http_basic do |username, password| username == 'username' && password == 'password' end end end※usernameとpasswordは、実際は環境変数で設定しています。
before_actionにif Rails.env.production?を追記して、本番環境でのみ適用するようにしました。
お陰で、テスト時はbasic認証せずそのままトップページへアクセスし、テストを実行できるようになりました!感想
まだまだ初学者なこともあり、エラーに直面すると問題箇所を真正面から解決しようとしがちです。
今回のように、エラーを避ける、「やらずに済む」方法が無いかと多方面から考えることも重要だと実感しました。本記事が初投稿でした。少しでも参考になれば嬉しく思います。
最後まで閲覧いただき、誠にありがとうございました。参考記事
ベーシック認証(Basic認証)とは?設定方法と注意点・エラーになる原因を解説
Rails×Basic認証×Rspecでつまづいた
RSpec3でBASIC認証がかかったアクションをテストする
Rails/Rspecテストをhttp基本認証で渡す
Basic認証を交えたテストコードの書き方
- 投稿日:2020-10-24T19:39:49+09:00
sudoを理解した上で使おう!
sudo
スーパーユーザ(や他のユーザ)の権限でコマンドを実行するときに使うコマンド。
コマンド 概要 -A パスワード入力用のコマンドを使用する(コマンドは「/etc/sudo.conf」または環境変数「SUDO_ASKPASS」で設定) -n パスワードを要求するプロンプトを表示しない(パスワード入力が必要なコマンドの場合はエラーとなって実行できない) -p 文字列 パスワード入力時のプロンプトを指定する(デフォルトは「:」記号) -S パスワードを端末ではなく標準入力から読み込む(パスワードの末尾には改行が必要) -k 保存されている認証情報を無効にする(次回のsudo実行時には必ずパスワード入力が必要)。コマンドと一緒に使用可能 -K 保存されている認証情報を完全に消去する -V 保存された認証情報を更新する -u ユーザー コマンドを実行するときのユーザーを「ユーザー名」または「ユーザーID(#記号と数字)」で指定する -g グループ コマンドを実行するときのグループを「グループ名」または「グループID(#記号と数字)」で指定する -P sudoを実行するユーザーが所属するグループのままコマンドを実行する
- 投稿日:2020-10-24T19:14:24+09:00
Rspecで多対多のFactoryを作ってSystemSpecでテストしたときのノート[RSpec, FactoryBot]
背景
Rspecで多対多の関係を作って、SystemSpecでテストをしました。
元々のテーブル構造の複雑さもあり、かなり苦労したので、以下にノートをまとめます。実行完了は下記の通りです。
- Rspec 3.9
- Rails 5.2.4.2
テーブル構造
テーブル構造は、このようになっています。メインのテーブルは、
offices
(ある会社の支社)とshops
(営業先である店舗)で、office
(支社)はevebt
を開いて、そこに営業先である店舗shops
が参加します。shops
は必ず何らかのcategory
を持っています。起こっていた問題
モデルメソッドの関係で、どうしても
events
のfactory
を作った時に、それに紐づく、shops
が必要になりました。しかし、構造上、このように書いたのでは、エラーが出てしまいました。let!(:shop){FactoryBot.create(:shop)} let!(:event){FactoryBot.create(:event)} #=> ここで eventに紐づくshopがないとエラーになる構造になっていた let!(:event_shops){FactoryBot.create(:event_shop, event: event, shop: shop)}対処方法
そこで、
event
のfactory
生成時に、同時に関連するshop
も定義できるようなfactoryを作成することにしました。eventsのファクトリを作る
作成したFactoryは以下のようになっています。
spec/factories/events.rbFactoryBot.define do factory :event do office_id { nil } name { "テストイベント" } trait :with_shops do after(:create) do |event| category = FactoryBot.create(:category, :sequence) create_list(:shop, 1, events: [event], category: category) end end end endまず、
event
のファクトリ内にwith_shops
というtraitを作成して、event
作成時に関連するshop
も作成できるようにします。create_list
でshop
のファクトリを複数作成でき流ようにし(ここでは1つしか必要ないので1つだけ)、events
からevent
のインスタンスが複数入れられるように、[event]
と配列で表記します。なお、
category
がわざわざtrait
を使って呼び出してあるのは、後ほど解説します。System Specで適切に呼び出せるようにする
spec/factories/categories.rbFactoryBot.define do factory :category do name { "医療系" } trait :sequence do sequence(:id, 100) name { "服飾系" } end end endspec/system/events_spec.rblet!(:event) { FactoryBot.create(:event, :with_shops, office: office, shops: [shop]) } # ここからcategoryをshopに当てはめることはできない次に、
category
のファクトリですが、ビューの中で、event
は複数回生成されます。そのため、同時に生成されるshop
のcateogory
は毎回別のid
(FK)にしないと、FKの重複エラーになってしまいました。また、
system spec
からevent
のshops
にcategory
を当てはめようとすると、spec/factories/events.rb
内で、shop
のファクトリを作成しようとしたときに、「外部キーが存在しません」とエラーになってしまいました。そのため、
sequence
を利用して、一つ一つ違うid
(FK)のcategoryを作成するようにしました。終わりに(参考サイトなど)
解決に長い時間がかかってしまいましたが、なんとか解決できてよかったです!
今回はDBの構造が複雑だったため、このような複雑なSpecを書かねばならなくなってしまいましたが、
今後はDB設計をしっかりして、もっとシンプルなテストで済むようにしたいです。。。。▼特に参考にさせていただいた記事など
- FactoryGirlで「多対多」や「複数の1対多」のアソシエーションを設定する
- Factorybotのtraitを使って、has_manyが2重にある複雑なassociation付きのデータを用意する
- FactoryBot (旧FactoryGirl) の sequence と .next
- 投稿日:2020-10-24T19:06:38+09:00
Rails 3 から PostgreSQL 10 に接続するときに使ったコード
Rails 3.0.1 で PostgreSQL 10 に繋いでテストする必要があり、 initializer を追加することになりました。
config/initializers/backport_pg_10_support_to_rails_3.rb
if Rails.env.test? module ActiveRecord class Base class << self def establish_connection(*arg) end end end end require 'active_record/connection_adapters/postgresql_adapter' module ActiveRecord module ConnectionAdapters class PostgreSQLAdapter < AbstractAdapter # Resets the sequence of a table's primary key to the maximum value. def reset_pk_sequence!(table, pk = nil, sequence = nil) unless pk and sequence default_pk, default_sequence = pk_and_sequence_for(table) pk ||= default_pk sequence ||= default_sequence end if pk if sequence quoted_sequence = quote_column_name(sequence) if ActiveRecord::Base.connection.select_value('SELECT version()').include?('PostgreSQL 10') # language=sql sql =<<-EOS SELECT setval('#{quoted_sequence}', (SELECT GREATEST(MAX(#{quote_column_name pk})+(SELECT seqincrement FROM pg_sequence WHERE seqrelid = '#{quoted_sequence}'::regclass), (SELECT seqmin FROM pg_sequence WHERE seqrelid = '#{quoted_sequence}'::regclass)) FROM #{quote_table_name(table)}), false) EOS else # language=sql sql =<<-EOS SELECT setval('#{quoted_sequence}', (SELECT GREATEST(MAX(#{quote_column_name pk})+(SELECT increment_by FROM #{quoted_sequence}), (SELECT min_value FROM #{quoted_sequence})) FROM #{quote_table_name(table)}), false) EOS end else @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger end end end end end end end
require 'active_record/connection_adapters/postgresql_adapter'
を入れて、def reset_pk_sequence!(table, pk = nil, sequence = nil)
を上書きしましたが、 それだけだとestablish_connection
が存在しないというエラーが出るので、require
の前にestablish_connection
を記述しました。
reset_pk_sequence!
は https://github.com/rails/rails/blob/3-0-stable/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb から基本的にコピーで、 変更したのは SQL 作成部分です。
- 投稿日:2020-10-24T18:30:07+09:00
Bootstrap4でflashメッセージに閉じるアイコンボタン(Dismissing)を実装する
前提条件
すでにbootstrap4を導入していてる人。
bootstrap3でもできますが少し記述が変わるので以下参考
https://bootstrap-guide.com/components/alerts
やりたい事
flashメッセージの横に✖️を出してメッセージを消せるようにしたい
(参考画像)http://drive.google.com/uc?export=view&id=1ckdEvoEdn79roPkAsarFpTbnf-pq_Ejl実装
以下のコードを部分テンプレートファイルに記載
layout/_flashes.html.erb<% flash.each do |key, value| %> <div class="alert alert-<%= bootstrap_alert(key) %> alert-dismissible fade show" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="閉じる"> <span aria-hidden="true">×</span> </button> <strong> <%= value %> </strong> </div> <% end %>コードの説明
<% flash.each do |key, value| %>
はコントローラなどでflashメッセージを記載したときにeachで毎回出るように回しています。
<span aria-hidden="true">×</span>
の×
は✖️のエスケープ文字です。正直これは直接✖️と書いても良いらしい。
エスケープ処理について理解したい方は下記のURLを参考に
https://qiita.com/n_hirai/items/df0a21d2409ee47973e5最後に
さすがbootstrap と言ったところでしょうか。少しの記述で簡単に実装できます。
エスケープ処理についても少し理解できたので良かったです。
- 投稿日:2020-10-24T18:25:38+09:00
RailsにVue.jsを導入する
備忘録
今回はrailsで開発中のアプリにVue.jsを導入したので備忘録として記録します。
初めてrailsでVue.jsを使う人の助けになればと思います。
また、初心者のため間違いなどあればご指摘お願いします!
ruby 2.6.5
Rails 6.0.3.3ステップ1webpackerのインストール
インストール済みの方はスキップして下さい
Gemgile内に記述gem "webpacker", github: "rails/webpacker”記述できたらbundle installしましょう。
インストールできたらターミナルで以下を実行
$ bin/rails webpacker:installこれでwebpackerのインストールが完了
ステップ2 Vue.jsのインストール
ターミナルで以下コマンドを入力
$ rails webpacker:install:vueこれでVue.jsに必要なファイルなどが作成されました。
ステップ3 Vue.jsの読み込み
app/views/layouts配下のapplication.html.erbファイルに以下を記述
<%= javascript_pack_tag "hello_vue" %>正常に読み込まれると写真のようにviewに表示されます。
https://gyazo.com/57e56686d2113920659f3dc9410f3a15最後に
以上でrailsでVue.jsを導入する事ができました!
比較的に簡単に導入する事ができるのでよければ使ってみて下さい!
何か間違えなどあればご教授下さい!
- 投稿日:2020-10-24T18:22:36+09:00
【Rails】video_tagで動画が再生されない
Railsのvideo_tagを使用した実装
Railsで画像を表示させる時は
image_tag
を使用しますが、動画を再生したい時にはvideo_tag
を使用します。
ところがどっこい動画が再生されないのはどうしてなのでしょう!
ちなみにRailsの公式ドキュメントは以下です。再生されない記述
<% @posts.each do |post| %> <%= video_tag(post.movie, size: "500x300", autoplay: true) %> <% end %>postsテーブルのmovieカラムからデータをとってきています。
動画サイズを500×300に指定、autoplay: true
とすることで自動再生されるはず、、、されません。原因とコード追加
Rails公式ドキュメントを見てもらえればわかる通り、
muted
というオプションがあります。
デフォルトだとmuted: folse
となっており、音声再生が行われる状態になっています。
自動で音声などが再生され始めるとユーザーにとって負担となるため、Chromeではautoplay
とmuted
がどちらも有効になっていないと自動再生されないようです。
muted
を追加した記述が以下です。<% @posts.each do |post| %> <%= video_tag(post.movie, size: "500x300", autoplay: true, muted: true) %> <% end %>おわりに
読んでいただきありがとうございました。
どなたかの動画再生で役に立てば幸いです。
- 投稿日:2020-10-24T16:48:06+09:00
[Rails]Active Storageの使用方法
はじめに
Active Storageを使うと、画像などのファイルのアップロードを簡単にするメソッドが使用できたり、画像を保存するテーブルを簡単に作成できます。
目次
- 画像加工ツールの導入
- Active Storageのインストール
- 画像の保存方法
- 画像の表示
1. 画像加工ツールの導入
まず画像加工に必要な画像変換ツールと、これをRailsから使えるようにするためのgemを導入します。
ImageMagicはコマンドラインから画像の作成やサイズ変更、保存形式などの変更ができます。
以下のコマンドを実行します。ターミナル
brew install imagemagickImageMagicはgemではないのでRubyやRailsで扱うには、MiniMagickというgemを導入する必要があります。
MiniMagicはImageMagicをRubyで扱えるようにするためのgemです。
次に画像サイズの変更をするためのgemをインストールします。
ImageProcessingはMiniMagicではできない、画像サイズを調整する機能を提供するgemです。
以下のようにgemfileの一番下に追記します。
その後、コマンドでbundle installを実行します。gemfilegem 'mini_magick' gem 'image_processing', '~> 1.2'2. Active Storageのインストール
ターミナルで以下を実行します。
ターミナル
rails active_storage:installActive Storageに関連したマイグレーションが作成されるので、続けて以下を実行します。
ターミナル
rails db:migrate3. 画像の保存方法
Active Storageのテーブルに画像を保存するために、アソシエーションの定義とimageカラムの保存の許可を設定します。
今回はhas_one_attachedメソッドを使って、一つの画像ファイルを添付できるようにしました。app/models/post.rbclass Post < ApplicationRecord ~略~ has_one_attached :image ~略~ endこれでpostsテーブルに画像ファイルの紐付けができました。
このとき、postsテーブルにカラムを追加する必要はありません。次にストロングパラメーターにimageを追加し、画像ファイルの保存を許可します。
app/controllers/posts_controller.rbclass PostsController < ApplicationController ~略~ def post_params params.require(:post).permit(:name, :image, :price, :evaluation, :description, :category_id, :shop_name).merge(user_id: current_user.id) end ~略~ end4. 画像の表示
Railsのヘルパーメソッドであるimage_tagメソッドを用いて画像を表示します。
例
<%= image_tag post.image, class: "post-img" %>attached?メソッドを使うことで画像が存在しないときのエラーを防ぐことができます。
例
<%= image_tag @post.image ,class:"user-box-img" if @post.image.attached? %>上記のように記述することで画像が存在する場合のみimage_tagが読み込まれます。
Active Storageを導入している場合、variantメソッドを用いることができます。
variantメソッドを使用することで、画像ファイルの表示サイズを指定することができます。例
<%= image_tag post.image.variant(resize: '500x500'), class: "post-img" %>
- 投稿日:2020-10-24T15:56:39+09:00
【rails】センテンス集
ヘルパーメソッド
ビューファイルではヘルパーメソッドを使用することができました。これまでに登場した「form_with」や「link_to」などもヘルパーメソッドであり、あらかじめ定義されている処理です。これらのヘルパーメソッドは、HTMLの要素が戻り値となっています。より詳しく言うと、文字列としてHTMLの要素が戻り値となる、ということです。
モジュール
モジュールとは、Rubyにおける「インスタンスを生成できないクラス」のようなもののことです。
下記のように定義します。module Sample1 class Test end end module Sample2 class Test end end Sample1::Test Sample2::Testクラスとモジュールの使い分けとして、具体的なオブジェクトを生成したい場合(インスタンスを生成したい場合)はクラスを使用し、処理だけ(メソッドなど)が必要な場合はモジュールを使用するという認識で構いません。
Helper
Helperとは、ヘルパーメソッドを作成できるモジュールです。
app/helpers配下に用意されており、application_helper.rbや、各コントローラーに対応したhelperのファイルに処理を記述することでヘルパーメソッドとして使用できます。実際には〇〇Helperという形で定義されます。module ApplicationHelper def sample # sampleというヘルパーメソッドです end endこのようにApplicationHelper内へメソッドとして定義すると、下記のようにビューファイルで使用できます。
<%= sample %>ビューファイルへRubyの処理をたくさん記述してしまった場合や、繰り返し同じ処理を記述する場合は、可読性が落ちてしまうのでヘルパーメソッドとして切り出しましょう。
- 投稿日:2020-10-24T14:58:14+09:00
開発を便利にしてくれるもの!
初めに
この記事ではオリジナル開発を便利にしてくれるツールを色々紹介していきます~
- vscodeの便利機能
- コンソールの出力を表形式に
1. vscodeの便利機能
zenkaku
これを防ぐために、全角を灰色にしてくれる拡張ツール "Zenkaku"をインストールしましょう。vscode左の四角が4つあるアイコンから拡張ツールを入手できます。
そうすると、以下のように全角が灰色になるので、全角エラーを撲滅できるでしょう!
japanese language pack ~
英語が苦手で日本語表記にしたいという方におすすめ!
拡張機能であるjapanese language pack ~をインストールし、vscodeを再起動すればメニューなどが日本語化されているはずです。
indent-rainbow
特にhtml/cssを開発しているとき、階層構造を半角スペース4つ分(tabキー)のインデントで表すと整理されて見やすくなります。
このインデントを虹色にしてくれる拡張機能が"indent-rainbow"です。ぜひインストールしておきましょう!auto close tag
タグの閉じ忘れや、タグが別タグとクロスしてしまうミスが起こりがち!
auto close tagはHTMLやXMLでタグを記載するときに、開始タグを打ち終わったときに自動的に終了タグを生成してくれるプラグインです。
HTMLやXMLを書いていて、特にタグの入れ子が多くなってきた時とか、終了タグを忘れてエラーになることってないですか?この Auto Close Tag を入れれば終了タグを毎回書かずに、開始タグを書いたら自動的にタグを閉じてくれます。
HTMLを書く効率が格段に上がるので、イチオシのプラグインです!
auto rename tag
さらに修正効率アップ!
auto rename tagは開始タグを修正したときに、自動的に対になる終了タグを修正してくれるプラグインです。
Auto Close Tagの親戚のようなプラグインです!。HTML/XMLの要素を修正することはよくあるかと思いますが、このプラグインは開始タグを書き換えれば終了タグも自動的に書き換えてくれるので、修正効率はとても上がるかと思います。
Auto Close Tagと併せて使うとあなたのVSCode環境は間違いなく快適になるでしょう!
Beautify
開発を行っていて、ついつい段落を変え忘れたりコードがガタガタになっても修正がめんどくさくなってしまうことはよくありますよね、、、
そんな方に!
BeautifyはJavascriptやCSS、SASS、HTMLコードを綺麗に整形してくれる拡張機能です!ガタガタのコードもCommand+Shift+Pでコマンドパレットを開き、beautifyでコマンドを選択すれば一発で綺麗にしてくれます。
endwise
自動でendを挿入してくれる拡張機能です!これでendを忘れる心配なし!
vscode-icons
vscode-iconsを導入すればファイルアイコンが見やすくなります!
HTML CSS Support
HTMLを書くときに、CSS側で作ったClass名が候補に出るようになります。よく書き間違いでスタイル当たってなかったりしますが、これならバッチリ。
live share
共同開発の効率が上がること間違いなし!
Live Share は、使っているプログラミング言語や構築しているアプリの種類に関係なく、リアルタイムで他のユーザーと共同で編集やデバッグができます。 現在のプロジェクトを瞬時に安全に共有したり、共同でデバッグ セッションを開始したり、ターミナル インスタンスを共有したり、localhost の Web アプリを転送したり、音声通話などを行うことができます!詳しい導入を知りたい方は下記を参考に↓
https://qiita.com/Shota_Fukuda/items/1358b8eb5e3e8354d1c72. コンソールの出力を表形式に
開発をしていると、データベースの中身(レコード)を確認したいときがよく来ます。コンソールを用いて確認できますが、初期状態では全レコードが横並びで非常に見づらいです。しかし、HitbというGemを利用すると、表形式で出力できるようになります。
まず、以下の二行をgemfileに記述します。
Gemfilegem 'hirb' gem 'hirb-unicode'その後、ターミナルにて
$ bundle installこの時点でHirbは利用できるのですが、毎回コンソール中にHirb.enableを入力する必要があります。面倒くさいのでデフォルトでHirbを利用するように設定します。
ルートディレクトリー(appやdbと同じ階層)に.irbrcファイル
を作成します。.irbrcファイル中に以下を記述します。
if defined? Rails::Console if defined? Hirb Hirb.enable end endこれにて、コンソールの出力がいつでも表形式になります!
- 投稿日:2020-10-24T14:45:55+09:00
【忘備録】Rails構築について
この記事は
初心者の自分がRailsを構築するにあたりメモを忘れないように記事にした。(2020/10/24時点)
Rails構築手順に関しては、下記の記事を参考に進めた。
【完全版】MacでRails環境構築する手順の全て1.Command Line Toolsインストール時に失敗した話
とりあえず記事通りにインストールしようとすると下記のエラーが発生した。% xcode-select --install xcode-select: note: install requested for command line developer toolsその後、下記のようなポップアップが表示された。
このソフトウェアは、現在ソフトウェア・アップデート・サーバから入手できないため、インストールできません。
[解決策]
・More Downloads for Apple Developers から自分の動作環境に合うXcodeをインストール。インストール後、Xcodeのバージョンを確認すると下記のエラーが発生
原因、対応方法について調査してみる。% xcodebuild -version xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance[解決策]
・完全版?Xcodeをインストール(自分はApp Storeからダウンロードしました)
インストール後、以下のコマンドを入力% sudo xcode-select -s /Applications/Xcode.app/Contents/Developer #↓↓Xcodeのversion確認↓↓ % xcodebuild -version Xcode 12.1 Build version 12A7403
- 投稿日:2020-10-24T14:24:22+09:00
[RuboCop]警告を無効化する方法
RuboCopに怒られすぎて嫌になってませんか?
「ここはしょうがないだろ!」と言いながらどうにか頑張って怒られないようにする経験が誰しもがあるかと思います。
そこで、警告を無効化するための方法を紹介します。
使いすぎてもRuboCopの意味がなくなるので注意ですが、使いどころを見極めて活用してみましょう!無効化する方法
指定範囲の全ての警告を無効化したい場合
# rubocop:disable all 〜ここに処理を記述〜 # rubocop:enable all指定範囲の特定の警告を無効化したい場合
# rubocop:disable Style/LineLength, Style/StringLiterals 〜ここに処理を記述〜 # rubocop:enable Style/LineLength, Style/StringLiterals単一行の全ての警告を無効化したい場合
for x in (0..19) # rubocop:disable all単一行の特定の警告を無効化したい場合
for x in (0..19) # rubocop:disable Style/AvoidFor
- 投稿日:2020-10-24T14:17:55+09:00
フォーム入力の結果を表示する方法
はじめて記事を書かせていただきます
プログラミングの学習をはじめて、1ヶ月の初心者ですruby on railsでfurimaアプリを作成しています
ユーザー登録をして、商品を出品し、他のユーザーが購入すると、取引が完了する流れです現段階の仕様では、ユーザーの出品商品の入力が終わると、topページに移動するようにしています
def create @item = Item.new(item_params) if @item.valid? @item.save return redirect_to root_path #topページに戻る else render :new end end*itemsテーブルに出品商品の情報が登録されます
ここで「商品の出品が完了しました」と表示されるページを追加し、topページへクリックで戻るようにする方法を検討しています
- コントローラーに、パスを記述する方法でやってみる
まず、結果表示のHTML文書を作成(kanryouとする)
routesファイルに記述resources :items do resources :orders, only: [:index, :create] member do get 'kanryou' end endコントローラーに記述
def create @item = Item.new(item_params) if @item.valid? @item.save return redirect_to kanryou_item_path(@item.id) else render :new end end以上でうまくいきました
参考にさせていただきました
https://qiita.com/imayasu/items/19f43a5726ed2170f611
- 投稿日:2020-10-24T14:17:38+09:00
[Rails]変換・検証・検索するためのメソッドまとめ
変換系のメソッド
to_h
ハッシュに変換するメソッド。
to_a
配列に変換するメソッド。
to_s
文字列に変換するメソッド。
to_i
数値に変換するメソッド。
to_sym
シンボルを返すメソッド。
encode
文字列の文字コードを変換する。
文字列.encode('UTF-8')gsub
特定の文字を別の文字へ置換したり、正規表現を用いて該当箇所を置換したり削除したりできる。
文字列.gsub(置換したい文字列, 置換後の文字列) 文字列.gsub(/正規表現/, 正規表現に該当した箇所を置換した後の文字列)compact
nilの要素を取り除いた配列を新しく生成して返します。
a = [1, nil, 'abc', false] b = a.compact b #=> [1, 'abc', false]join
配列要素を指定したもので区切ることができるメソッド。
p ["apple", "orange", "lemon"].join(',') #=> "apple,orange,lemon"each_slice
ある要素数ごとに分割したい場合に使う。
[1..10].each_slice(2) do |num| puts num end #=> [1,2,3,4,5],[6,7,8,9,10]検証系のメソッド
request.post(patch,get,delete)?
リクエストの種類がpost(patch,get,delete)かどうかを検証している。
valid?
バリデーションを実行した結果、エラーが無ければtrue、あればfalseを返す。
invalid?
バリデーションを実行した結果、エラーが無ければfalse、あればtrueを返す。
present?
値があればtrue、なければfalseを返す。
nil?
nilの場合のみtrue、それ以外はfalseを返す。
empty?
空の文字列や配列の場合にtrue、それ以外はfalseを返す。(nilに使うとエラーになる。)
blank?
nilか空の場合はtrue、それ以外はfalseを返す。
zero?
中身が0(無いか)を調べるメソッド。文字列やtrue&false以外に使える。
any?
中身が存在する際にtrueを返すメソッド。一件だけ検索するので高速処理。2つ目と3つ目は同義。
Sample.where(name: "侍1").any? #=> true Sample.any? do | sample | sample.name == "侍1" end #=> true Sample.any? { | sample | sample.name == "侍1" } #=> trueyes?
ユーザーがyesといった場合にtrueを返す。
freeze! if yes?("Should I freeze the latest Rails?") list << '土曜日' if holiday_saturday&.yes?検索系のメソッド
pluck
テーブルから指定したカラムの配列をデータ型で返す。
Product.pluck(:id)map
各要素へ順に処理を実行してくれるメソッド。
配列変数.map {|変数名| 具体的な処理 } array = ["a", "b", "c"] array = array.map {|item| item.upcase } #=>["A", "B", "C"]detect
各要素をブロックで評価し「真(true)」となる要素の最初の1件を返す。findメソッド的なやつ。
array = [1, 2, 3, 1, 2, 3] detect = array.detect {|v| v==1 } #=>1
- 投稿日:2020-10-24T13:45:25+09:00
さまざまなマイグレーション操作を使いこなす
マイグレーションの適用を理解しよう
1.「マイグレーション」ファイルを作成し、RubyでDBの構造(スキーマ)を変更するコードを記述
2.作成した「マイグレーション」ファイルをrails db:migrateコマンドを使ってデータベースに適用する(migrateする)。$ rails db:migrateマイグレーションファイルの更新・変更・削除はコマンドを実行しないと適用されない。
マイグレーションの上げ下げ
マイグレーションを適用する = 上げ
適用を取り消す = 下げschema.rb
Railsは現在のデータベース構造をdb/schema.rbに自動出力します。
マイグレーションのを適用したり外したりすると自動的に出力され、またdb:schema.rb:dump
で手動出力する事も可能
- 投稿日:2020-10-24T13:34:21+09:00
[Github]開発時によく使うコマンドまとめ
ブランチの作り方
$ git checkout develop $ git checkout -b 作成するブランチ名 $ git push -u origin 作成したブランチ名プルリクエスト作成方法
1.以下のコマンドを実行する。
$ git add . $ git commit -m "コミット内容" $ git push origin develop2.右上の緑色のCompare & pull requestボタンをクリック。
3.プルリクエスト内容を記入する。
4.どのブランチからどのブランチにpull requestするかを確認する。
-例-
developブランチからsampleブランチへのpull requestsample ... develop
5.「Create pull request」ボタンを押して、Pull Requestを作成。
最新情報をローカルに反映させたい時
1.commit、pushまで終わらせた状態で以下のコマンドを実行する。
git checkout develop git pull origin develop git checkout 開発用ブランチ git merge origin develop2.もし、コンフリクトが発生した場合は、以下を実行する。
# コンフリクト内容を解消した上で、、 $ git add . $ git commit -m "コミット内容" $ git push origin 開発用ブランチ $ git merge origin develop
- 投稿日:2020-10-24T13:12:58+09:00
N+1問題を甘く見るな!
はじめに
これまで「N+1問題」というものを知ってはいたものの、そこまで規模の大きい開発をしたことが無かったのであまり意識してこないまま今日まで過ごしてきました。。
しかし、実際に現場で働くと、規模が大きい開発ではデータの件数が何万件というものはザラにあるのでこれからは意識しないといけないと気付かされました(泣)
皆さんも、実際に現場入った際に必ずと言っていいほど必要な知識だと思うので是非ここで押さえておいてください!!
※ちょくちょくSQL用語が出てきますが、そこは理解している程で進めさせていただきます。まず、N+1問題とは?
簡単に言えば、ループ処理の中で都度SQLを発行してしまい、大量(必要以上)のSQLが発行されてパフォーマンスが低下してしまう問題のことです。
一つ例えを出しましょう。
AさんというUserのProduct(商品)を10件取得して、Aさんの商品一覧ページを表示したい時には、、AさんのUserデータを取得するために1回
10件のProductsデータを取得するために10回
の合計11回のクエリを発行し、表示したいデータを取得することになります。11件ほどでは大したことはないのですが、これが10000件や20000件だと大変です。
1回のクエリで0.001秒の時間がかかるとして、10000件とか20000件だと10秒や20秒もレスポンスに時間がかかってしまいます。ここまで待たされるのは面倒ですよね?
この問題はコードの書き方次第で解決することが出来て、
適切に書けば、仮に10000件のProductsであっても、2回のクエリで取得できるんです(笑)問題解決するためのメソッドたち
さて、この問題を解決するためのやり方を見ていきましょう。
基本的には以下で紹介する4つのメソッドを活用していけば良いです。使いどころはそれぞれ少し違ったりするので使い分けられるように出来るようにしましょう。
メソッド キャッシュ クエリ 用途 データ参照 joins しない INNER JOIN 絞り込み できる eager_load する LEFT JOIN キャッシュと絞り込み できる preload する JOIN せずそれぞれSELECT キャッシュ できない includes する 場合による キャッシュ、必要なら絞り込み できる joins
デフォルトでINNER JOINを行う。LEFT OUTER JOINを行いたい時はleft_joinsを使う。
このメソッドは、キャッシュしないのでメモリを必要最低限に抑えることが出来ます。
また、JOINした先のデータを参照せず、絞り込み結果だけが必要な場合などに使えば良いです。User.joins(:products).where(products: { id: 1 }) # SELECT `users`.* FROM `users` INNER JOIN `products` ON `products`.`user_id` = `users`.`id` WHERE `products`.`id` = 1eager_load
指定したassociationをLEFT OUTER JOINで引いてキャッシュする。
クエリが1つで済むので高速処理が可能です。
1対1あるいはN対1のアソシエーションをJOINする場合(belongs_to, has_one)や、JOINした先のテーブルの情報を参照したい場合(Whereによる絞り込みなど)の際に使えば良いです。User.eager_load(:products) # SELECT `users`.`id`, `users`.`name`, `users`.`created_at`, `users`.`updated_at`, `products`.`id`, `products`.`user_id`, `products`.`created_at`, `products`.`updated_at` FROM `users` LEFT OUTER JOIN `products` ON `products`.`user_id` = `users`.`id`preload
指定したassociationを複数のクエリに分けて引いてキャッシュする。
しかし、アソシエーション先のデータ参照(Whereによる絞り込みなど)は出来ません。
多対多のアソシエーションの時に使ったら良いです。注意点としては、データ量が大きいと、IN句が大きくなりがちで、メモリを圧迫する可能性があるので注意する。User.preload(:products) # SELECT `users`.* FROM `users` # SELECT `products`.* FROM `products` WHERE `products`.`user_id` IN (1, 2, 3, ...)includes
簡単に言うと、eager_loadとpreloadを使い分けてくれます。
しかし、includesは利用しない方が良いっぽいです。
なぜなら、includesは、preloadとeager_loadをよしなに振り分けるので。preloadと、eager_loadの特徴を理解していれば、includesが登場する場面は、ほとんどないと思います。データが少ないうちはincludesしていても問題にならないかもしれませんが、データが増えてきたときにジワジワと問題が顕在化してくるので、includesの挙動も正しく知っておきましょう。User.includes(:products) # SELECT `users`.* FROM `users` # SELECT `products`.* FROM `products` WHERE `products`.`user_id` IN (1, 2, 3, ...)Bullet gemを使いこなしN+1問題を早期発見する
どれだけ気を付けていても抜けが出てしまうのが人間です。
そこをカバーしてくれるgemがBulletです。Bulletの使い方
1.Gemfileに以下を追記する。
group :optimization do gem 'bullet', '~> 6.1.0' end2.実行環境をoptimizationとして、development.rbをコピーして、以下を記述する。
config/enviroments/optomization.rbconfig.after_initialize do # 最適化することを許可している。 Bullet.enable = true # 問題点をJSのAlertで表示することを許可している。 Bullet.alert = true # ログをファイルにとることを許可している。 Bullet.bullet_logger = true # ブラウザのコンソールにN+1問題を表示することを許可している。 Bullet.console = true # BulletがRailsのログに記録することを許可している。 Bullet.rails_logger = true # 問題点をフッターに表示することを許可している。 Bullet.add_footer = true end3.webpacker.ymlに、以下を追記する。
webpacker.ymloptimization: <<: *development4.実行してN+1問題をチェックする。
$ bundle exec rails server -e optimizationテスト環境でのBulletの設定方法
1.test.rbに以下を追記する。
config/enviroments/test.rbconfig.after_initialize do Bullet.enable = true Bullet.bullet_logger = true Bullet.raise = false end2.spec_helper.rbに以下を追記する。
spec/spec_helper.rbif Bullet.enable? config.before(:each) do Bullet.start_request end config.after(:each) do Bullet.perform_out_of_channel_notifications if Bullet.notification? Bullet.end_request end end終わりに
ここまでN+1問題についてどのように対応していけばいいかを見てきました。
少しの意識を変えるだけでかなりレスポンスが早くなると思います!
では、今この時から意識して開発していきましょう!!!参考
Ruby on Railsのコードに潜むN+1クエリ問題をBullet gemで発見して、Railsサイトのレスポンスを最適化
ActiveRecordのincludesは使わずにpreloadとeager_loadを使い分ける理由
- 投稿日:2020-10-24T12:02:09+09:00
Rails 投稿とユーザーの紐付け
はじめに
今、メモアプリを開発をしています。
全てのメモの一覧が表示されてしまうのですが、どうにか
メモ一覧ページにログインユーザーのメモのみの一覧を表示したいです。今回はそれについて学習していきます。
メモとユーザーの紐付け
まず、各投稿が誰がしたのかを判別するためにnotesテーブル(投稿系のテーブル)に、user_idというカラムをたす。
class CreateNotes < ActiveRecord::Migration[5.2] def change create_table :notes do |t| t.text :title t.integer :user_id t.integer :category_id t.text :explanation t.timestamps end end end$ rails db:migrate:resetメモに投稿したユーザーのidを保存
投稿を保存する際に、先ほど追加したuser_idカラムにも情報を入れる。
buildメソッドについてnotes.controller.rbdef create @note = current_user.notes.build(note_params) @note.save redirect_to notes_path endメモ一覧ページにユーザーの投稿をのみを表示する。
<div class='container'> <div class='row'> <h2>メモ一覧</h2> <table class='table'> <thead> <tr> <th>タイトル</th> <th>カテゴリー</th> </tr> </thead> <tbody> <% @notes.each do |note| %> <% if user_signed_in? && current_user.id == note.user_id %> #ここを追加 <tr> <td> <%= link_to note_path(note) do %> <%= note.title %> <% end %> </td> <td><%= note.category.name %></td> </tr> <% end %> <% end %> </tbody> </table> </div> </div>メモ一覧のeach文(繰り返し)の中に記述。
<% if user_signed_in? && current_user.id == note.user_id %>この記述でログインしているユーザなのか?とログインユーザーのidとメモを投稿したユーザのidが同じか見ている。
trueなら表示される!
これで大丈夫だと思います!最後に
説明が分かりにくいと思いますが何かの参考になれば幸いです。
また、間違っているところがあればご教授いただけるとありがたいです。
- 投稿日:2020-10-24T11:59:07+09:00
Ruby buildメソッド
buildメソッド
親モデルに属する子モデルのインスタンスを新たに生成したい場合に使うメソッド。
(親モデルと子モデルは、アソシエーション設定あり)
外部キーに値が入った状態でインスタンスが生成できる。ユーザーに紐づくメモインスタンスを生成したい場合
※UserモデルとNoteモデルは、1対多のアソシエーションを設定しているとします。note.controller.rb@note = current_user.notes.build(note_params) ## 親モデル.子モデル.buildという形式生成されるコメントインスタンスの中身
*pry-byebugで@noteインスタンスの中身を確認@note id: nil, title: "aaa", user_id: 2, category_id: 1, explanation: "ppppp", created_at: nil, updated_at: niluser_idに値が入っています。
- 投稿日:2020-10-24T10:22:30+09:00
【Ruby on Rails】Formオブジェクト(ActiveModel)のエラーメッセージを日本語化する方法
本記事の概要
・Formオブジェクトのバリデーションエラーが日本語にならない問題に悩んだので、備忘録として残しておきます。
・+α余談としてActiveRecordとActiveModelの違いについて少し触れました。開発環境
Mac OS Catalina 10.15.4
ruby 2.6系
rails 6.0系前提条件
gem 'rails-i18n'を導入してデフォルトの言語設定はすでに日本語にしています。
また、configのlocalsディレクトリにja.ymlファイルを作成済みです。エラーメッセージを日本語化できなかった原因とその対策
結論から言うと、今回作成したFormオブジェクトは
include ActiveModel:Model
によってactivemodelを継承したモデルであったにも関わらず
activerecordを継承したモデルとして日本語化を行おうとしたのが問題だったよう。<誤っていたコードの記述>
ja.ymlja: activerecord: models: detail: 詳細情報 posts_tag: 投稿 attributes: user: name: 名前 detail: age: 年齢 pr: PR文 area_id: 居住地 occupation_id: 職業 interest_id: 興味 posts_tag: title: タイトル content: 概要 name: タグ<正しいコードの記述>
ja.ymlja: activerecord: models: detail: 詳細情報 attributes: user: name: 名前 detail: age: 年齢 pr: PR文 area_id: 居住地 occupation_id: 職業 interest_id: 興味 activemodel: models: posts_tag: 投稿 attributes: posts_tag: title: タイトル content: 概要 name: タグ余談
ちなみに、
rails g model
で生成するデフォルトモデルが継承しているActiveRecordとActiveModelの違いは、DBとのやり取りが可能か否かにあります。前者は、可能なのでモデル名.findなどですでに保存してあるデータを引っ張ってこられますが、後者のActiveModelは通常findメソッドは使えません。
他にも、バリデーションにおける`
validates uniqueness: true
等も、DBに保存されているデータを参照して一意性かどうか判断するので、ActiveModelで記述することはできません。そんな感じで便利な一方、割とActiveModelはややこしいですね...
なにはともあれ、最後までお読み頂きありがとうございました!
- 投稿日:2020-10-24T02:41:57+09:00
Railsのbundle installで見かけないエラーが…それに対する解決法
はじめに
最近、講義やゼミでの研究も相まってAWS Cloud9でrailsを使う機会が増えている。
そんな中で初めて見たエラーだった。ネットで検索してもいまいち解決法が分かりにくかったので、ここにメモがてら残そうと思う本題
では、どんなエラーが出たのか。以下の様なエラーだ。
$ budle install There was an error while trying to write to `/tmp/bundler-compact-index-xxxxxxxxx(date)-xxxxxx-xxxxxxx/versions`. There was insufficient space remaining on the device.ほほう…何だろう。最後の一文を見るとデバイスの容量が足りないという事みたいです。
という事は・・・デバイスのボリューム自体を増やす。もしくは使いそうにないファイルの中身を消去して、空きを作るなどが考えられます。では、前者を解決策1、後者を解決策2としたいと思います。解決策1
これは、AWS Cloud9のボリュームを増やすという事です。記事がすでに上がっているので割愛したいと思います。
解決策2
では、何処のファイルの中身を消去しようとなりますが、私は/var/logを使う事が今回は無さそうなのでそちらを消去することにしました。その際に使用したコマンドが以下です。
$ sudo find /var/log/ -type f -name \* -exec cp -f /dev/null {} \;最後に
という訳で、2つの解決策を提示しました。これで、容量が足りるようになると思うので、再度bundle installして貰えれば大丈夫です。
恐らくもっと良いやり方もあると思います。最後までお読みいただきありがとうございました。
- 投稿日:2020-10-24T02:41:39+09:00
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such table: main.follows~
フォロー機能を実装するためにUserモデルと中間テーブルのRelationshipモデルを作成。
model/user.rb. . def follow(other_user) unless self == other_user self.relationships.find_or_create_by(follow_id: other_user.id) end endこんな感じでfollowメソッドを作り、relation_controllerの該当アクション内で呼び出したところ、タイトルのエラーが出てきた。
テーブルがないと言われているけど必要なテーブルがあることはschemaファイルからも確認できたので混乱。
原因
原因としてはrelationshipsテーブルを作るときのmigrationファイルに問題があった
db/migrate/time_create_relationships.rbclass CreateRelationships < ActiveRecord::Migration[5.2] def change create_table :relationships do |t| t.references :user, foreign_key: true t.references :follow, foreign_key: true t.timestamps end add_index :relationships, [:user_id, :follow_id], unique: true end endこちらのfollow_idカラムを作成する部分、
t.references :follow, foreign_key: true
のforeign_keyがtrueとなっている部分が原因でした。
foreign_keyがtrueになっているとid名と同じテーブルが存在するか、つまりありもしないfollowテーブルがあるかを確認してしまうため、エラーが吐き出されていたようです。解決法としては該当部分に
db/migrate/time_create_relationships.rbt.references :follow, foreign_key: { to_table: :users }と参照するテーブルを記述することで正しく動作しました。
rails g model relationships follow:references
とターミナルで自動作成されたマイグレーションファイルはデフォルトでforeign_key:true
となるので気を付けたいところです。