20210907のRubyに関する記事は13件です。

Fakerを利用したダミーモデルの作り方

Fakerとは ダミーデータを生成してくれるgem。 様々な種類が用意されている。 seeds.rbとは テーブルにデータを作成するファイル。ここにダミーデータを生成するコードを書く 導入方法 Gemfileに以下を記述してbundle install Gemfile gem 'faker' $ bundle install 例えばusersテーブルに10件、Boardテーブルに20件のダミーデータを追加したい場合。 app/db/seeds.rb 10.times do User.create!( last_name: Faker::Name.unique.last_name, first_name: Faker::Name.unique.first_name, email: Faker::Internet.unique.email, password: "12345678", password_confirmation: "12345678" ) end 20.times do |index| Board.create!( user: User.offset(rand(User.count)).first, title: "タイトル#{index}", body: "本文#{index}" ) end 書いた後は、 $ bundle exec rails db:seed を実行する事でseedで書いた内容がデータベースに反映される。 実装ポイント ①create!を使う seedの実行が失敗した場合にエラーを発生させるため。 createだと失敗した場合にエラーとならないため。 ②Faker::Name.first_name Fakerの中にあるNameのfirst_nameメソッドを使いますよ。という意味。 ③User.offset(rand(User.count)).first offset 指定した位置からレコードを取得する rand 疑似乱数を発生させる first 最初のレコードを発生させる User.count 今回はusersテーブルに10件分のダミーデータを作成しているので、10個 つまり、randメソッドにより0~9未満の整数を起点とし、そこから最初の1件を取得する ということ。 ではでは
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Fakerを利用したダミーモデルの作り方

Fakerとは ダミーデータを生成してくれるgem。 様々な種類が用意されている。 seeds.rbとは テーブルにデータを作成するファイル。ここにダミーデータを生成するコードを書く 導入方法 Gemfileに以下を記述してbundle install Gemfile gem 'faker' $ bundle install 例えばusersテーブルに10件、Boardテーブルに20件のダミーデータを追加したい場合。 app/db/seeds.rb 10.times do User.create!( last_name: Faker::Name.unique.last_name, first_name: Faker::Name.unique.first_name, email: Faker::Internet.unique.email, password: "12345678", password_confirmation: "12345678" ) end 20.times do |index| Board.create!( user: User.offset(rand(User.count)).first, title: "タイトル#{index}", body: "本文#{index}" ) end 書いた後は、 $ bundle exec rails db:seed を実行する事でseedで書いた内容がデータベースに反映される。 実装ポイント ①create!を使う seedの実行が失敗した場合にエラーを発生させるため。 createだと失敗した場合にエラーとならないため。 ②Faker::Name.first_name Fakerの中にあるNameのfirst_nameメソッドを使いますよ。という意味。 ③User.offset(rand(User.count)).first offset 指定した位置からレコードを取得する rand 疑似乱数を発生させる first 最初のレコードを発生させる User.count 今回はusersテーブルに10件分のダミーデータを作成しているので、10個 つまり、randメソッドにより0~9未満の整数を起点とし、そこから最初の1件を取得する ということ。 ではでは
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

9.7振り返り

js呼び出す時にcreateでredirect_to入れて呼び出せなくなった def new @calender = Calender.new end def create @calender = Calender.new(calender_params) @calender.patient_id = current_patient.id @calender.save #jsの時は↓入れると読み込まれなくなる # if @calender.save # redirect_to patient_calenders_path # else # render :index # end end $('ここの指定が違う') apprication.js $(function () { ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ここに違うもの入れてエラーになって表示できない $('#calendar_test').fullCalendar({ selectable: true, header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, ブラウザでconsoleを使ってエラーを確認する  console log "run"を走らせてどこまで動くか確認  引数の指定が違ってエラー                 undefined local variable or method `patient パスを確認する /staff/patients/:patient_id/records/new(.:format) から :patient_idが必要であることがわかるので指定する @patient = Patient.find(params[:patient_id]) staff/records#new new_staff_patient_record_path GET /staff/patients/:patient_id/records/new(.:format) staff/records#new class Staff::RecordsController < ApplicationController def new @record = Record.new #@patient = Patient.find(params[:id])では情報がとれないというエラー #routesでpathを確認  records#new の /staff/patients/:patient_id/records/new(.:format) #引数を次のように直す @patient = Patient.find(params[:patient_id]) end routesのパスが /staff/ostomies/:ostomy_id/comments(.:format) なら :ostomy_id  が必要になる     /staff/ostomies/:id なら :id が必要になる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

末尾の文字列を3回出力するプログラムの作成

Ruby問題集から。 sliceメソッドを使って作成するのですが、今回ピックアップしたいのは模範解答にあるlengthメソッドについての所感というか愚痴というか私の知識不足の露呈というかをつらつら書いていきます。 まずは構成から。 問題 以下の要件を満たすextra_endメソッドを実装しましょう。 ・対象の文字列から末尾にある2文字を取得すること ・取得した2文字を3回繰り返して出力すること 【ヒント】 qiita.rb # 配列を作成します array = [0,1,2,3,4,5,6] # 配列から引数で指定した要素を取得します ele1 = array.slice(1) puts ele1 #=> 1 # 配列番号-4から4つ分の要素をsliceします ele2 = array.slice(-4,4) puts ele2 #=> 3, 4, 5, 6 # 配列はもとのままです puts array #=> [0,1,2,3,4,5,6] この段階で末尾の文字列 = ヒントに記載されている3つ目の'配列番号-4から〜'あたりを使用するのかなと。 ここで模範解答と私の回答を並べてみます。 qiita.rb 〜模範解答〜 def extra_end(str) char_num = str.length right2 = str.slice(char_num - 2, 2) puts right2 * 3 end 〜私の回答〜 def extra_end(str) num = str.slice(- 2, 2) puts num * 3 end メソッドの実行結果は同じなんですよ。(私の記述の方が可読性た...) ここで模範解答の解説文を見ると、、、 extra_end('Hello')でメソッドを呼び出した場合の解説をします。 まず、1行目のextra_endメソッドの仮引数strには対象の文字列’Hello’が格納されます。 そして、2行目ではstrに対してsliceメソッドを使用し、指定した要素を取り出しています。 sliceメソッドの1つ目の引数では、文字列(Hello)の後ろから2番目の要素を基準点としています。 そして、2つ目の引数により、基準点から2つ分の要素を取り出しています。 今回の場合、「H,e,l,l,o」の後ろから2番目の要素は「l」です。そして、基準点「l」から2つ分の要素である「lo」が取り出されるので、end_str = loとなります。 最後に、2 * 3と記述することによって、「lololo」と出力されます。 、、、lengthメソッドいります? そもそも記述方法は多様にあることを理解した上で、lengthメソッドいります? 今回の問題文では「末尾の文字列を3回」と記述があり、【ヒント】にはsliceメソッドにて配列番号後ろから指定する記述もあり、解説文では「sliceメソッドの1つ目の引数では、文字列(Hello)の"後ろから2番目の要素を基準点"としています。」と書かれております。 lengthメソッド定義してわざわざ代入して(char_num -2, 2)ってhelloの場合(3, 2)ってなるわけでこれ前から3番目ですやん!!! 5文字中の前から3番目も後ろから2番目も同じだけども!!! 今回に限り私のコードの方が可読性た、、、っ!!! はい。というわけで実行結果は同じでも、sliceメソッドでは文字列に対するアプローチがコードによって前からなのか後ろからなのか変わる会でした。() 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

送信中の暗号化をtrueにしたredisにsidekiqから接続する

前提 sidekiqを導入するにあたり、privateネットワーク内ではあるがアプリとredis間の通信を暗号化しようとなった。 それにあたりredisへの接続ができない問題に当たったのでその修正を覚書 ※ redisにはElastiCache for redisを利用 結果 以下のように設定した上で以下を環境変数から注入 REDIS_URL=rediss://aaa.aaa.aaa.0000.apne1.cache.amazonaws.com:6379 REDIS_AUTH_TOKEN=**** # config/initializers/sidekiq.rb Sidekiq.configure_client do |config| config.redis = { url: ENV.fetch("REDIS_URL") { "redis://127.0.0.1:6379" }, password: ENV.fetch("REDIS_AUTH_TOKEN") { nil }, } end Sidekiq.configure_server do |config| config.redis = { url: ENV.fetch("REDIS_URL") { "redis://127.0.0.1:6379" }, password: ENV.fetch("REDIS_AUTH_TOKEN") { nil }, } end つまづきポイント 本番の環境では通信を暗号化したいがローカルでは暗号化せずさっと実装したい passwordのデフォルトをnilにすることでローカルでは非暗号化で対応可能 本番では rediss:// に指定する うまくいかなかったケース redisでパスワードなしで接続しようとした Redis::TimeoutError: Connection timed out が発生 何故なのかはいまいちわからないですがタイムアウト扱い port同じなので認証エラーとかになるのかなと思ったらタイムアウトでした rediss指定でパスワード追加していない Redis::CommandError: NOAUTH Authentication required. が発生
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

No route matches [GET] "/logout"の解決

誤り等ありましたらご指摘ください 前提 -Rails 6.1.4 -ruby 2.6.8 問題 rails tutorial 8章を学習中、ログアウト機能を追加したので試してみた所、下記エラーが発生。 No route matches [GET] "/logout" 調べても「jQueryがない!」と言った記事が多く、チュートリアルでは過程でインストールしている為、解決の糸口は見つからず、丸二日悩みに悩んで見つけたのが、"link_to"を"button_to"に置き換える事だった。 _header.html.rb <%= link_to "Log out", logout_path, method: :delete %> _header.html.rb <%= button_to "Log out", logout_path, method: :delete %> しかしこれではデザインが崩れてしまい、私の意に反する。 解決 これを app/javascript/packs/application.js require("@rails/ujs").start() require("turbolinks").start() require("@rails/activestorage").start() require("channels") require('jquery') こう app/javascript/packs/application.js import Rails from "@rails/ujs" import Turbolinks from "turbolinks" import * as ActiveStorage from "@rails/activestorage" import "channels" Rails.start() Turbolinks.start() ActiveStorage.start() application.jsの記述をRail6.1.3.2のデフォルトの仕様に合わせたら機能した。 心折れそう。 参考 Rails6でjqueryが読み込めない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】includesメソッドと部分テンプレートを繰り返しrenderにする事によってN+1問題を回避する

N+1問題とは? SQLが必要以上に実行されてしまいパフォーマンスが落ちる問題のことです。 それぞれのモデルに (Userモデル) has_many :boards (Boardモデル)belongs_to :user といった定義を施すことで、関係性を定義することができます。 N+1問題はアソシエーション有りの時に生じる問題であり、上記の例で言うと掲示板の一覧を表示する際にユーザーの名前を取得するために掲示板の数だけSQLが発行されてしまいます。 具体的には次のようなコードになります。 app/controllers/boards_controller.rb class BoardsControllere < ApplicationController def index @boards = Board.all end end app/views/boards/index.html.erb <% @boards.each do |board| %> <%= render partial: 'board', locals: { board: board } %> <% end %> 上記の書き方では「Boardモデルから掲示板一覧情報」を1回取得し、「紐ついたuser_idをuserの数だけ」(n回)取得しています。 そしてview画面でパーシャルを呼び出し、@boardsをeach文によって繰り返し表示しています。 この方法でも表示はされますが、SQLが多く発行され、遅くなったりパフォーマンスが下がるんですね。 includesメソッドで関連付けを一括読み込みをする includesは、関連付いたモデルのデータを先に取得するメソッドです。このメソッドを使うことで、Boardモデルからデータを取得する際に、関連するUserモデルのデータもまとめて取得してくれます。 app/controllers/boards_controller.rb class BoardsController < ApplocationController def index @boards = Boards.all.includes(:user).order(created_at: :desc) end end 部分テンプレートを繰り返しrenderにする 上記のコードではパーシャルを呼び出し、each文によって繰り返し表示されていました。 そこを下記のように変更します。 app/views/boards/index.html.erb <%= render @boards %> だいぶスッキリしましたね。 これは@boardsというふうに複数形にすることによって、Railsが「_board.html.erb」を自動的に探してくれています。 【コラム】部分テンプレートの省略形 実は単数形インスタンスを渡す場合と複数形インスタンスを渡す場合では書き方が少し異なります。 それらの書き方を順番に見ていきます。 単数形インスタンス変数を渡す boardsフォルダ内の_board.html.erbを呼び出すとします。そして、@boardをテンプレート内で変数boardとして使用するとします。 ①基本形 render partial: 'boards/board', locals: { board: @board } 「partial: 」以下でファイル名を指定し、「locals: 」以下の記述で、@boardを部分テンプレート内で変数boardとして使用しています。 board = @board ということですね。 ②省略形パターン1 render 'boards/board', board: @board 単に「partial」と「locals」を省略しただけの形となります。 ③省略形パターン2 render @board インスタンス変数とファイル名が同じ場合、上記のような省略形にすることができます。 かなりスマートな記述になりました。 複数形のインスタンスを渡す ②省略形パターン1 render partial: 'boards/board', collection: @boards collectionオプションは、渡されたインスタンスの要素をそのテンプレートを繰り返し表示する事ができるオプションです。 つまりコレクションの中のインスタンスが部分テンプレートに呼ばれる変数となるため、each文を使用せずに繰り返し処理ができます。 ③省略形パターン2 render @boards ファイル名と複数形sを除いたインスタンス名が一致しており、かつeach文のように繰り返し表示したい場合は、上記のように省略することができます。 今回の場合だと_board.html.erbと@boardsなので、一致しているということになります。 さらに表現を変えると、 render @boards という省略形は、 <% @boards.each do |board| %> <%= render partial: 'board', locals: { board: board } %> <% end %> 上記の形に書き換える事もできます。 少しややこしいと思いますが、renderの書き方にはいろいろあるので整理してみてください。 ではでは
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Example title

Example
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Example title

Example
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

本番環境にてGmailを送信する【Rails】

本日の内容 今回の記事のですが、本番環境(EC2)にてGmailを送る実装になります。 開発環境でも参考になると思います!(記述する場所を変えるぐらいなので) 環境・前提 ruby 2.6.5 本番環境EC2 ◇Gmailメール実装 こちらでは、本番環境にてgmailからユーザーにメールを送っていきます。 流れ ①Gmailアカウント/アプリパスワード取得 ②コードに記述 Gmailアカウント/アプリパスワード取得 gmailのアカウントのアプリパスワードが必要です。(通常のログインパスワードだとエラーが出ます) 今回は、gmailアカウントの2段階認証をオンにして、アプリパスワードを取得ます。 ① 送信用に利用するgmailのアカウントで ログイン ② [セキュリティ]設定  画面左のメニューから[セキュリティ]を選択し、セキュリティの設定画面を開きます。 ③ 2段階認証を有効化  [Googleへのログイン]にある[2段階認証プロセス]を選択し、画面に沿って設定を完了させてください。  ※既に有効な場合は、手順をスキップしてください ④ アプリで利用するためのパスワードを取得します。  [Googleへのログイン]にある[アプリパスワード]を選択し、パスワードを発行してください。 ※上記の後に出てくる、アプリパスワードを生成するアプリとデバイスを選択してください、のアプリ選択は「その他」で大丈夫です。 ⑤ パスワード取得完了  発行完了すると、16桁の番号が払い出されます。  この番号をこの後コードに記述します。 コードに記述 config/environments/product.rbに下記の記述を行えば完了です! 開発環境の場合は、config/environments/development.rbに記述すればOKです config/environments/product.rb config.action_mailer.default_url_options = { host: "Elastic IP アドレス" } #ECの本番アドレス config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :enable_starttls_auto => true, :address => 'smtp.gmail.com', :port => '587', :domain => 'smtp.gmail.com', :authentication => 'plain', :user_name => '自身のGmail', :password => 'アプリパスワード'#先程発行した16桁のパスワードを記述 } 以上になります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最初のGemfileの作り方

テキストコピペでもいいんですが、npm init 的な事できないのかなと思い調べました。 bundle init で Gemfile を生成できました。 参考 https://bundler.io/gemfile.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【RSpec】KeyError: Factory not registered:を解決した方法

対象者 RSpecテストを実施した際にKeyError: Factory not registered:というエラーが出ている方 目的 上記エラーを解消して、テストを正常に作動させる 実際の手順と実例 1.結論(解決策) aliasを用いて、「spec/factories/user.rb」内のuserに「,aliases: [:follower,:followed] 」と追加して解決 2.エラー内容と前提 フォロー機能のテスト実行時に出たエラーが下記の通り Factoryに"followed"が登録されていないと予想 下記 model/relationship.rb class Relationship < ApplicationRecord # followerがフォローした人、followedがフォローされた人 belongs_to :follower, class_name: "User" belongs_to :followed, class_name: "User" end model/user.rb class User < ApplicationRecord has_many :reverse_of_relationships, class_name: "Relationship", foreign_key: "followed_id", dependent: :destroy has_many :followers, through: :reverse_of_relationships, source: :follower has_many :relationships, class_name: "Relationship", foreign_key: "follower_id", dependent: :destroy has_many :followings, through: :relationships, source: :followed end spec/factories/relationships.rb FactoryBot.define do factory :relationship do association :followed association :follower end end spec/factories/users.rb FactoryBot.define do factory :user do name { Faker::Lorem.characters(number: 4) } nickname { Faker::Lorem.characters(number: 4) } email { Faker::Internet.email } introduction { Faker::Lorem.characters(number: 20) } password { 'password' } password_confirmation { 'password' } end end spec/models/relationship_spec.rb require 'rails_helper' RSpec.describe Relationship, type: :model do let!(:relationship) { FactoryBot.create(:relationship) } describe "モデルのテスト" do it "有効なRelationshipの場合は保存されるか" do expect(build(:relationship)).to be_valid end end end 3.エラー原因 Relationship.rbで belongs_to :follower, class_name: "User" belongs_to :followed, class_name: "User" と記述しているように,アソシエーションに別名をつけている場合はFactoryの方にも別名を付ける必要があります。 なので、users.rbを上記の内容を追加します。 spec/factories/users.rb FactoryBot.define do factory :user, aliases: [:follower,:followed] do :   #上記を追加 (中略) : end aliasとは既存のメソッドに対して別名をつけることができるRubyメソッドのひとつです。 Rubyのaliasとalias_methodでメソッドに別名を付ける方法【初心者向け】 これで解決しました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

method(メソッド)について

・復習+学習始めたての方に method(メソッド)とは? プログラミングにおける処理をまとめたもののこと 定義の仕方 def say_hello puts "Hello"  メソッドの定義の部分 end say_hello    メソッドの実行 実行結果 Hello と出ます! 初投稿なので、簡単なのを簡単にまとめてみました。 これからどんどん分かりやすく楽しみめるような投稿していきます!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む