- 投稿日:2020-10-27T23:30:13+09:00
Ruby returnメソッドの使い方について
returnとは??
メソッドの戻り値を返す方法。Rubyにおいては、
return
をわざわざ使用せずとも、定義したメソッドにおいて、最後に処理された値が返ってくる。しかし、途中で処理を抜け出したい場合は、
return
を使用することで、強制的に値を返すことができる。例題
■returnを使用しない場合
def total price = 1000 num = 10 "#{price}円の服を#{num}枚購入したので、合計は#{price*num}円になります。" "1枚返品したので、合計は#{price*(num-1)}円になりました。" end p total結果
1枚返品したので、合計は9000円になりました。
return
を使用しない場合、最後に定義した文言が出力されます。■returnを使用する場合
def total price = 1000 num = 10 return "#{price}円の服を#{num}枚購入したので、合計は#{price*num}円になります。" "1枚返品したので、合計は#{price*(num-1)}円になりました。" end p total結果
1000円の服を10枚購入したので、合計は10000円になります。
return
を使用すると、return
後に定義した文言が出力されました。このように、もし途中で処理を抜けたい場合は
return
を活用すると良いでしょう。
ちなみにまだ私はreturn
を使用する場面には遭遇していません、、、笑
- 投稿日:2020-10-27T23:16:29+09:00
【rails】first_or_initialize
first_or_initializeについて学習したため、アウトプットいたします。
first_or_initializeとは?
first_or_initializeの使い方は?の順に記述します。
first_or_initializeとは?
whereで検索した条件のレコードが存在すればそのレコードのインスタンスを返し、存在しなければ新しくインスタンスを作るメソッドです。
と言ってもなかなかわかりませんよね。
詳しく説明します。例えば、
studentというテーブルがあったとして、そこのデータベース上に10人の名前がそれぞれ登録されていたとします。first_or_initializeメソッドは、
そのデータベース上にそのstudentがいなかった場合→そのstudentを新規登録します。
一方、
studentがすでに登録されていた場合→その生徒の情報を取ってきます。少しづつわかってきましたか?
すなわちこのメソッドの特徴は
「データの重複を避けること」なんです。ではどうやって使うのでしょうか?
first_or_initializeの使い方
student = Student.where(name: "佐藤").first_or_initialize存在しなければ新しくインスタンスを作りたいオブジェクトを定義し、
その後に
where(条件).first_or_initialize
とすると完成です。上記の例では、
そのデータベース上に佐藤さんがいなかった場合→その佐藤を新規登録します。
一方、
佐藤さんすでに登録されていた場合→佐藤さんの情報(id, age等定義したもの)を取ってきます。
- 投稿日:2020-10-27T23:12:50+09:00
メソッドについてのアウトプット その2です
メソッドのアウトプット その2 引数です
その1ではメソッドをの中でif文を使用してみました。
※前回の記事です。メソッドについてのアウトプットです その1
今回は引数を使って、もう少しコードをすっきりしたいと思います!
前回のコードです。
sample.rbdef register eraser = 110 pen = 150 bill = eraser + pen if bill >= 200 #200円以上のお買い上げは10%off!! bill * 0.9 end end puts register #registerメソッドを呼び出す。こちらの
eraser と pen
の数値をメソットの外で定義してみます。sample.rbdef register eraser = 110 # ここの数値 pen = 150 # ここの数値 bill = eraser + pen if bill >= 200 bill * 0.9 end end puts register
def register
の後ろに()
そ追加してその中に
eraser
とpen
を入れてあげます。sample.rbdef register(eraser, pen) # eraserとpenの間に カンマ(,)と半角スペース # eraser = 110 ここは削除 # pen = 150 ここは削除 bill = eraser + pen if bill >= 200 bill * 0.9 end end puts register(150, 100) # ここに数値をいれる
puts register(150, 100)
この二つの数値は
def register(eraser, pen)
ここに送られます。
それぞれeraser
には150
pen
には100
が送られます。sample.rbdef register(eraser, pen) bill = eraser + pen if bill >= 200 bill * 0.9 end end puts register(150, 100)すくしだけすっきりしましたね!(多分)
今日のアウトプットでした。
- 投稿日:2020-10-27T22:03:08+09:00
RubyOnRails Udemyの無料講座でエラーが発生、それを解決、最後まで貫く
RubyOnRails Udemyの無料講座でエラーが発生、それを解決、最後まで貫く
RubyOnRails学習をはじめた人で以下のUdemyの無料講座を受講したが、エラーで躓き最後まで修了できなかった方々のために、身をもって経験したエラーと解決方法を共有します。
【最短30分でできる!】Ruby on Rails入門: 初心者でも簡単! ブラウザ
エラーが発生した時点-1
原因、解決方法-1
原因は'paperclip'がrailsのバージョンに依存しているからだ。
よく確認したところ、講座はRubyonRails 5.2をベースにしているとの記載があった。
僕の方だと、現時点でPaizaCloudはRubyonRails 6系が標準になっていた。1.ターミナルにて「gem list rails」を打ち、railsのバージョンを確認しよう。
*僕の場合のバージョンは
6.0.2.1,
5.0.7.2,
5.0.6
だった。2.プロジェクトを新たに作成しよう。
*講座としては、「9.プロジェクトの作成」に戻ろう。
3.ターミナルにて、「rails (version) new boardgame-app --database=mysql」を打ち、RubyOnRails 5系を使用するプロジェクトを作成する。
*僕の場合は、RubyOnRails 5.0.7.2 を使用した。動作確認-1
1.講座の通り進もう。
2.「14. 画像ファイルの追加、編集機能の追加」のコースにて、動作を確認したところ、エラーなく進行された。localhost:3000 にても問題なし。
ーーー
エラーが発生した時点-2
原因、解決方法-2
原因は不明だが、他と違って「<%= from...」を使っていることが原因のようだった。
1.「<%= from...」を「<%= f...」に書き換える。
動作確認-2
- localhost:3000にて問題なく表示された。
ーーー
Laravelも同じだと思うが、バージョンによる予期せぬ不備(記述方法が異なったり、packageが使えなくなったりする等)が多々あった。エラーに遭っても挫折せず、皆が力を合わせ取り組んで解決したら良いと思う。
無料講座はエラーに遭遇した時でも、講師に質問ができないことがある。
本投稿がRubyOnRailsを学習始めている方々が諦めずに最後まで貫くための原動力になることを祈る。
- 投稿日:2020-10-27T21:53:26+09:00
Rails学習 3日目その2
Ruby on Rails5速習実践ガイド chapter7
7-1 登録や編集の実行前に確認画面をはさむ
登録する前に確認画面が出てきてそこで確認してからデータが登録されるように設定する。
まずは確認画面が表示されるアクション(conform_newアクション)をコントローラーに書くapp/controller/tasks_controller.rbdef confirm_new @task = current_user.tasks.new(task_params) render :new unless @task.valid? #もしデータベースに@taskがなかったら実行その次にルーティングを記入
config/routes.rbresources :tasks do post :confirm, action: :confirm_new, on: :new endpost :confirm, action: :confirm_new, on: :new
この部分は元々以下の形であったconfig/routes.rbresources :tasks do new do post :confirm, action: :confirm_new end endnewブロック内に要素が一つだけの場合は後ろにon: :ブロック名とすることでルーティングがかける
次に確認画面のビューを作る
app/views/tasks/confirm_new.html.slimh1 新規内容の確認 = form_with model: @task, local: true do |f| table.table.table-hover tbody tr th= Task.human_attribute_name(:name) td= @task.name =f.hidden_field :description tr th= Task.human_attribute_name(:description) td= simple_format(@task.description) =f.hidden_field :description =f.submit '戻る', name: 'back', class: 'btn btn-secondary mr-3' =f.submit '登録', class: 'btn btn-primary'7-1-3 登録アクションで「戻る」ボタンからの遷移に対応する。
上記の確認画面のビューには戻るボタンと登録ボタンの2つがある。戻るボタンを機能させようと思ったらこの二つのボタンのどちらが押されているかの判断をする必要がある。そのために戻るボタンにはname属性にbackをつけた。プログラミング上ではもしname属性のbackが押されたら元に戻るという操作になる。
つまりparams[:back]の結果が出れば良い。
params[:back]が押されると元に戻るという動作をcreateアクションに書けば良いapp/controllers/tasks_controller.rbdef create @task = current_user.tasks.new(task_params) if params[:back].present? #present?は値がある場合trueとなる真偽値 render :new return end真偽値で使うメソッドの種類
メソッド名 メソッドの意味 nil? 変数の値がnil、または値がないときにtrueになる empty? 変数の値が""(文字列の場合)や値が空白の場合、真となります。nil?との違いは、empty?は変数の値はあることはあるが、その値が空を示しているところ blank? 値と言えるものがない場合にtrueとなる present? 値と言えるものがある場合はtrueとなる 7-2 一覧画面に検索機能を追加する
タスク一覧にあるタスクの数が多くなってくるといちいち探し出すのがめんどくさくなってくる。そんな時に検索機能があった方が便利だろう。
検索機能をつけるにはRansackというgemを使う7-2-2 名称による検索
Ransackを使って検索機能を追加するapp/controllers/tasks_controller.rbdef index @q = current_user.task.ransack(params[:q]) @task = @q.result(distinct: true).recent end@q = current_user.task.ransack(params[:q])
ransackではquery parameter(params[:q])を取って検索をかける
ログイン中のユーザーのtaskをransackで検索しそれを@qと置いている@task = @q.result(distinct: true).recent
検索で出た@qを
重複する検索結果を除外しつつ(result(distinct: true))
登録日時の並びで表示する(recent)ransackが実装できたので実際にビューで検索できるようにしてみる
検索機能の追加にはsearch_form_forを使うapp/views/tasks/index.html.slimh1 タスク一覧 = search_form_for @q, class: 'mr-5' do |f| .form_group.row =f.label :name_cont, '名称', class: 'col-sm-2 col-form-label' .col-sm-10 =f.search_field :name_cont, class: 'form-control' .form-group.row =f.label :created_at_gteq, '登録日時', class: 'col-sm-2 col-form-label' .col-sm-10 = f.search_field :created_at_gteq, class: 'form-control' .form-group =f.submit class: 'btn btn-outline-primary' = link_to '新規登録', new_task_path, class: 'btn btn-primary mb-3'name_cont:nameと部分一致している物を選ぶ。
.search_field:記入場所
created_at_gteq:記入した投稿日時より大きい(未来:gteq)の投稿を選ぶ7-3 一覧画面にソート機能を追加する
app/controllers/tasks_controller.rbdef index @q = current_user.task.ransack(params[:q]) @task = @q.result(distinct: true).recent endrecentでソートをしていたが次は任意の順番でソートをする
まずresentをとるapp/controllers/tasks_controller.rbdef index @q = current_user.task.ransack(params[:q]) @task = @q.result(distinct: true) endapp/views/tasks/index.html.slimtable.table.table-hover thead.thead-default tr th= sort_link(@q, :name, default_order: :desc) th= Task.human_attribute_name(:created_at) thsort_linkをつけるとソート操作ができるようになる
第一引数にはransackによって得られた値(ここでは@q)
第二引数にはソートを行う対象のカラム(ここではname)
default_order: :desc7-4 メールを送る
Railsはメールを送るためにメイラーという仕組みを利用している。メイラーを使いメールを作成・送信する。
メイラーはメイラーファイルに記述するapp/mailers/task_mailer.rdclass TaskMailer < ApplicationMailer def creation_email(task) @task = task mail( subject: 'タスク作成完了メール' to: 'user@example' from: 'taskleaf@example' ) end endsubjectやto、fromといった情報のmailをcreation_emailメソッドとしておく
7-4-3 メールの送信処理
実際にメールを送信できるようにしていく
app/controllers/tasks_controller.rbdef create @task = current_user.tasks.new(task_params) if params[:back].present? render :new return end if @task.save TaskMailer.creation_email(@task).deliver_now redirect_to @task, notice: "タスク「#{@task.name}」を登録しました" else render :new end end上記のようにTaskMailer.creation_email(@task).deliver_nowをつけると@taskについてのメールが送信される。deliver_nowは即時送信を行うためのメソッド。他にもdeliver_laterメソッドも存在している
7-5 ファイルをアップロードしてモデルに添付する
Active Storageというファイル管理gemが出てきて、それらを使って写真や画像を添付する
実際に添付するには以下の方法で添付するapp/models/task.rbclass Task < ApplicationRecord has_one_attached :image .... endhas_one_attachedメソッドを使うことによって1つのタスクに1つの画像(image)を紐付けることが可能になる。
app/views/tasks/_form.html.slim... ... ... .form-group =f.label :image =f.file_field :image, class: 'form-control' ... endja.ymlにも「image:画像」と設定しておく
task_paramsメソッドのpermitもimageも許可しておく確認画面にも表示されるようにコードを書く
app/views/tasks/show.html.slim... tr th= Task.human_attribute_name(:image) td= image_tag @task.image if @task.image.attached? tr ... ... ...if @task.image.attached?は画像が添付されているかどうかを表す。
実際に画像があればimage_tagで表示する7-7 ページネーション
タスクが多くなればなるほど今までやっていた情報を全て表示する方法では動作が重たくなってきてしまう。ページネーションは一定数以上のファイル数になればそれ以上の表示は次のページへ渡すなどをし、ページによって情報を分散させ動作を軽くする方法。
このページネーションにはkaminariというgemファイルが用いられる。元々のtasks_controllerファイルを
app/controllers/tasks_controller.rbdef index @q = current_user.task.ransack(params[:q]) @task = @q.result(distinct: true) end.page(params[:page])を後ろにつけることによって1ページあたりに表示する件数を決めることができる(デフォルトで1ページ25件)
app/controllers/tasks_controller.rbdef index @q = current_user.task.ransack(params[:q]) @task = @q.result(distinct: true).page(params[:page]) end次に実際にビューファイルに反映されるようにする
app/views/tasks/index.html.slim.mb-3 =paginate @tasks =page_entries_info @tasks ... ... ...paginateヘルパーメソッドとpage_entries_infoヘルパーメソッドを使うことによって自動的に作成してくれる。
7-8 非同期処理や定期実行を行う(Jobスケジューリング)
Railsではバックグラウンドで様々な処理を非同期に行うためのActive Jobというフレームワークが用意されている。ActiveJobは以下の時に使われる
・処理が重たくユーザーを待たせてしまっている
・指定した日時にアクションを起こしてほしいそんな時に使うのがsidekiqという仕組みである
①まずRailsとsideskiqを同期する
config/environments/development.rbconfig.active_job.queue_adapter = :sideskiq②app/jobs/sample_job.rbを作りperformメソッドを作る
app/jobs/sample_job.rbclass SampleJob < ApplicationJob queue_as :deault def perform(*args) Sidekiq::Logging.logger.info "サンプルジョブを実行しました" end endperformメソッドを呼び出して処理する
app/controller/tasks_controller.rbdef create @task = current_user.tasks.new(task_params) ... if @task.save TaskMailer.created_email(@task).deliver_now SampleJob.perform_later ... ... ...SampleJob.perform_laterが非同期処理を行うようになる
7-8-3 実行日時指定
setメソッドを使うと日時を指定して処理を実行できるようになる
#翌日の正午に実行 SampleJob.set(wait_until: Date.tomorrow.noon).perform_later #1週間後に実行 SampleJob.set(wait: 1.week).perform_later
- 投稿日:2020-10-27T21:14:37+09:00
Rubyの条件分岐(case,while,無限ループ,break)
Rubyの条件分岐
case文
条件分岐を表現するための文法。複数の条件を指定する時に、if文のelsifを重ねるよりもシンプルにコードを書くことができる
samplecase 対象のオブジェクトや式 when 値1 # 値1に一致する場合に実行する処理 when 値2 # 値2に一致する場合に実行する処理 when 値3 # 値3に一致する場合に実行する処理 else # どれにも一致しない場合に実行する処理 endwhile文
繰り返し処理を行うためのRubyの構文。指定した条件が真である間、処理を繰り返す
samplenumber = 0 while number <= 10 puts number number += 1 end # ターミナル出力結果 # 0 # 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10無限ループ
処理が永遠に繰り返されること
samplenumber = 0 while true puts number number += 1 end # ターミナル出力結果 # 0 # 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # . # . # .上記のコードは条件式の部分にはじめからtrueと書くことによって意図的に無限ループを発生させている
break
eachメソッドやwhile文などのループから脱出するために使われる
samplenumber = 0 while number <= 10 if number == 5 break end puts number number += 1 end # ターミナル出力結果 # 0 # 1 # 2 # 3 # 4このようにif文などの条件分岐とbreakを使うと、特定の条件のときにループを脱出することができる
現場からは以上です!
- 投稿日:2020-10-27T20:34:19+09:00
ActiveHashはアソシエーションをしっかり設定しよう
※結果を知りたい方は下の方までスクロールしてください。
エラー発生
商品を出品する機能を実装中のこと…
原因を探る
コントローラーの記述は間違ってないよね…
item_controller.rb 一部割愛class ItemsController < ApplicationController def create @item = Item.new(item_params) if @item.valid? @item.save redirect_to root_path else render :new end end private def item_params params.require(:item).permit(:name, :info, :price, :category_id, :status_id, :delivery_charge_id, :shipment_source_id, :date_of_shipment_id).merge(user_id: current_user.id) end endうん…大丈夫
ええー
じゃあモデルかなぁitem.rbclass Item < ApplicationRecord validates :name, :info, :price, presence: true validates :category_id, :status_id, :delivery_charge_id, :shipment_source_id, :date_of_shipment_id, numericality: { other_than: 1 } belongs_to :user has_many :comments has_one :buyer extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :category, :status, :delivery_charge, :shipment_source, :date_of_shipment endいや、記述の抜け漏れもないし、半角全角もスペルも大丈夫
バリデーションも大丈夫(←これが落とし穴)ビューファイル(割愛)は…うーん大丈夫そう
そして、インターネットの海を彷徨うこと30分…
本当にわからんしゃあないか
助け舟を呼ぶことに
大海に投げ出されたような気分だったのでもうこれは人に聞くしかあるまい
某短期講習中なので頼もしい方々に聞くことはできる早速原因究明に向けて色々と思案してくださった
ありがたや〜?…
これを、あれを試し、色々触っていった結果どうやらモデルの記述に問題があった模様
class Item < ApplicationRecord validates :name, :info, presence: true validates :price, presence: true validates :category_id, :status_id, :delivery_charge_id, :shipment_source_id, :date_of_shipment_id, numericality: { other_than: 1 } belongs_to :user has_many :comments has_one :buyer extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :category belongs_to_active_hash :status belongs_to_active_hash :delivery_charge belongs_to_active_hash :shipment_source belongs_to_active_hash :date_of_shipment end
↓つまりはこの部分↓belongs_to_active_hash :category belongs_to_active_hash :status belongs_to_active_hash :delivery_charge belongs_to_active_hash :shipment_source belongs_to_active_hash :date_of_shipmentここを別々に書くだけ!
バリデーションなんやからまとめて書かせてくれや…と思ったが、この話をしていると聞いていたうちの一人が
「それバリデーションじゃなくてアソシエーションですよ」
…まじかぁ…
まじかぁぁぁぁ!!!恥ずかしいぃ!///
そういやそうだわ!思いっっきりBelongs_toって書いてあるし!
なんなら俺がActiveHashを導入してた時にrails gで生成してたものは?モデルだよ!
モデルを生成してたんだよ!
それを関連付けるんだからアソシエーション以外に何があんの!知らなかったとはいえ思いつく材料は目の前にあった訳だ
反省するとともに判断材料が増えたので一歩前進したと思う
本当に今回は勉強になった
真摯に対応してくれた方ありがとうございました
- 投稿日:2020-10-27T18:18:52+09:00
Uncaught ReferenceError: Vue is not definedが起こった話
はじめに
Vue.jsをCDN読み込みで簡単なミニアプリを使う際に起こったエラーです。
備忘録のため残しておきます。初学者のため間違えがあればご指摘下さい!Uncaught ReferenceError: Vue is not defined
vue.jsの動作確認をするため以下のコードを記述したところvue.jsが読み込まれませんでした。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="vue.css"> <title>Document</title> </head> <body> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button>カウントアップ</button> </div> <script src="vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </body> </html>//vue.js new Vue({ el: '#app', data: { number: 0 } })解決策は簡単。
下から3行目のVueを使うためのCDNをjsが読み込まれるより上に記述するだけです。
headタグの中に入れるかbodyタグの一番上に記述しましょう。<!-- 修正後 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <link rel="stylesheet" href="vue.css"> <title>Document</title> </head> <body> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button>カウントアップ</button> </div> <script src="vue.js"></script> </body> </html>最後に
Vue.jsの超初心者の方の助けになれば幸いです。
- 投稿日:2020-10-27T16:11:31+09:00
ISUCON10 Online event
こんにちは, This is Santosh.I participated in ISUCON2020 Online event, It was held on September 12,2020.
Rules and regulations are mentioned on the official sites. please go through once(~5 minutes)
http://isucon.net/archives/54704557.html
Around 500~ teams participated on that day, It was fun as my first isucon! let's move to the technical side,
There was an application given「isummo」、It was about finding chair(isu in japanese) by different conditions. The goal was to improve the search time and processing speed of isummo application.
lightly just go through the following;
・http://sinatrarb.com/
・new relic
ruby version check-install,start mysql(may be it will helpful next time too)
If any login issue with mysql just try this or follow stackoverflow↓
mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_passwAbout coding language, you can choose any language Rust, Python, Go, Php or whatever you are comfortable with,I did with ruby as other team member were very familiar with it.Now the question is how to optimize our isummo app?
① Check all SQL queries -> Add index, as no index key was there
eg. SQL -> select * from isuumo.chair where kind = 'some value'
check kind is indexed or not ,if not -> KEYkind
(kind
)
adding index is easy as soon as you find the query, and it's fasten our app to some level.(rank was going up & team was enjoying)② Index based on order BY ASC OR DESC
eg; select * from issumo.desk where some_condition order by popularity DESC;
Please not here, order by have column by DESC, and the default index we add earlier will be ASC .To speedup execution of query make it, DESC INDEX, -> KEYpopularity
(popularity
DESC)
https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html
After this our app performance increased a bit.③ Next, find n+1,source code and try to fix that,
this was a bit tough ,I tried but there was no such improvement in speed.
Other things can be done on infrastructure side,as other member was doing that part I don't have much idea about it. Next isucon will try to cover up infra as well.
Good luck everyone for next event!
- 投稿日:2020-10-27T15:59:52+09:00
binding.pryの追加(rails)
ターミナルにて(追加したいディレクトリ)を「cd ~ 」で指定する。
VSCodeで(追加したいディレクトリ)のgemfileを開き、「gem 'mysql2', '0.?.?'」の「mysql2」のあとのバージョンを「'0.5.3'」に変更し、
「gem 'mysql2', '0.5.3'」とする。gemfileの一番下に「gem 'pry-rails'」と記述し、ターミナルに戻る。
ターミナルにて、bundle updateをするとgemがインストールされる。mysql2のバージョンが既に変更されていたら、pry-railsを記述した後に「bundle install」をすると導入される。
間違いなどあれば、ご指摘いただけるとありがたいです。
- 投稿日:2020-10-27T14:51:07+09:00
Railsで日付比較の検索の書き方
Ruby2.7.1
Rails6.0.3.3
で確認久しぶりにRailsでDBの検索処理を書いていて日付の比較の検索ってどう書くんだと調べていたのでメモ書き。
調べてるとたいてい、SQLを書くかArel使うかみたいのばっかで他に無いのかと調べていたら下記のような書き方でもいけた。[0] pry(main)> User.where(created_at: ..DateTime.now) User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`created_at` <= '2020-10-27 14:41:26.943067' [ [0] #<User:0x000055861898f208> { :id => 1, :created_at => Tue, 27 Oct 2020 14:18:54 JST +09:00, :updated_at => Tue, 27 Oct 2020 14:18:54 JST +09:00, } ]逆は
User.where(created_at: DateTime.now..) User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`created_at` >= '2020-10-27 14:52:57.534880'へぇって感じ。
- 投稿日:2020-10-27T14:36:18+09:00
Rails学習 3日目
Ruby on Rails5速習実践ガイド chapter6
6-2-1 「ルート」を構成する5つの要素
ルーティングとはリクエストをどのアクションで実行するかを指定するもの。ルーティングを構成するのに必要な物は以下である
要素の名前 要素の内容の例 説明 HTTPメソッド GET,POST,PATCH,PUT,DELETE 情報の送信、取得の方法を表す物 URLパターン /tasks、/tasks/:idなど URLそのもの URLパターンの名前 new_task、tasksなど 定義したURLパターンごとに一意な名前をつけたもの コントローラー tasks(Taskcontroller) 呼びたいアクションのコントローラークラスを指定する アクション index 呼びたいアクションを指定する 6-2-5 resourcesでCRUDのルート一式を定義する
前の説明でresourcesについて説明した今回はそれの応用編である。
/config/routes.rbresouces :tasksこのように記述するとtaskルーティングの7つのHTTPメソッドが自動的に1つにまとまる。ということを書いた。それではそれ以外のルーティングを書きたいときはどうすれば良いのか?プラスで付け加えたい時はcollectionを使う
/config/routes.rbresouces :tasks do collection do get 'export' end endこのようにcollectionのなかにHTTPメソッドとアクション名を書くことで自動的にルーティングが機能するようになる。
6-3 国際化
ja.ymlファイルなんかによりプログラミングでも日本語対応させてコードを書くことが可能である。利用者もまた日本語に対応したサービスにはなるが外国のかたが使う機会があるかもしれない。利用者によって言語を変える必要も出てくる。そんな時に使うのがI18n.localeである。I18nは一つのプログラムで複数の国向けに使えるようにするものである。
class ApplicationController < ActionController::Base before_action :set_locale private def set_locate I18n.locale = current_user&.locale || :ja #ログインしていなければ日本語 end endコントローラに定義することで使えるようになる
6-6 Railsのログ
ログとは自分が何か処理をしたときの履歴である。もしエラーやバグがあればログを遡り何の操作が正しくなかったかなどをみることができる。
例えばタスク作成時に保存したタスクの情報をログ出力させたい時は、以下のようにする。app/controllers/tasks_controller.rbdef create if @task.save logger.debug "task: #{@task.attributes.inspect}" redirect_to @task, notice: "タスク「#{@task.name}」を登録しました" elseinspectはわかりやすく表示してくれるもの。
ただログに残ってはいけない個人情報なんかもある、その時にはログに映らないようにしなければならない。
config/initializers/filter_parameter_logging.rbRails.application.config.filter_parameter +=[:password]ここで指定されたパラメータの値は、ログ上では[FILTERED]と表示される。
- 投稿日:2020-10-27T14:32:38+09:00
[Rails]Google Analytics コンバージョンタグを設定する
目標(コンバージョン率の測定)とは
Google Analyticsの機能で、「会員登録」「コンテンツ登録」「5ページ以上の閲覧」など目標を設定することにより、Webサイトの指標を出すことができます。
僕のWebサイト( https://www.mini4wg.com/ )でも目標設定をしたので、設定項目や実装方法などを解説していきます。目標設定 1/3
テンプレートが準備されており非常に便利です。google analyticsを指定してあれば、サイトに手を入れ図に対応することもできます。
しかし、画面遷移などによってはコンバージョンタグを仕込むなどの準備が必要になります。最初の目標では
- 収益
- 集客
- 問い合わせ
- ユーザーのロイヤリティ
など良く使われる項目が最初から定義されています。自分のサイトにあった目標を設定しましょう。目標の説明 2/3
目標の説明では測定のタイプを設定します。
- 到達ページ
- 滞在時間
- ページビュー数
- イベント
が設定できます。目標の詳細 3/3
目標の説明(2/3)で設定したタイプにより、ここのフォームが変化します。
イベントを選択した場合は、Webサイトからeventを送信する必要があります。
到達ページや滞在時間やページビューはGoogle Analyticwの画面から設定するだけで利用可能です。Railsでイベントを送信する場合
僕のサイトでも画像を登録する機能があるのですが、コンバージョンを測定するのに作成時に一度だけ送信したい時に下記の様な実装を行いました。
※ gtag.jsかanalytics.jsかでevent送信のコードが違うのでご注意ください。
僕のサイトではコンテンツ送信を測定する場合,ECサイトではよくある[thanks.html]などのサンクスページないため、
作成時に一回限りだけjavascriptのタグを出力し、google analyticsにeventを送信する様にしました。ProductsController
rubyclass ProductsController < ApplicationController =省略= def create @product = current_user.products .build(product_params) authorize @product if @product.save flash[:cv] = true redirect_to @product, notice: t('.saved') else render :new end end =省略= endviews/products/show.html.slim
slim~~省略 - if flash[:cv] == true javascript: gtag('event', 'created', { 'event_category': 'products', 'event_label': '#{@product.id}'}); ~~省略確認方法
実際にeventの送信が行われているかは下記のChrome Extensionを入れることにより、どんなeventが送信されているかわかります。
Page Analytics (by Google) - Chrome ウェブストア https://chrome.google.com/webstore/detail/page-analytics-by-google/fnbdnhhicmebfgdgglcdacdapkcihcoh/related?hl=ja
最後に
目標設定をすることにより、サイトの改善に役立てると共に人に説明する時にも指標があると非常に便利です。
- 投稿日:2020-10-27T12:33:04+09:00
initializeメソッドの役割について
initializeメソッド萌えという謎のジャンルを一人で開拓していた時期があったんですが受講生様からクラスとインスタンス、インスタンスメソッドとクラスメソッドの分類と役割の違いについてよく質問を受けるので、改めて上記リンク先記事で言及しているものをコード化しようと思います。
【イニシャライズが可愛いって話】
→ https://qiita.com/yamazaki_akihiro/private/32ea4cf5e653913d2485class Mother def initialize(sleeper) puts "#{sleeper}の部屋に入りましたが起きる気配はありません。実に穏やかな寝姿です" @sleeper = sleeper end def ding_frypan puts "「イヤーーーッッ!!!」※フライパンをガンガン鳴らしています。割と近所迷惑です" puts "「グワーーーッッ!!!」#{@sleeper}の断末魔!" end def open_curtain puts "「イヤーーーッッ!!!」※カーテンを勢いよく開けました。レールに負荷をかけるのであまり推奨されません" puts "「グワーーーッッ!!!」#{@sleeper}の断末魔!" end def strip_duvet puts "「イヤーーーッッ!!!」※布団をひっぺがしました。これがラブコメならこのあと色々あって二人は遅刻しますが今回は違います" puts "「グワーーーッッ!!!」#{@sleeper}の断末魔!" end def self.go_job puts "「遅刻してもお母さん知らないからね!」" puts "そして母は朝靄に包まれた街へ消えていった..." end end puts "7時です。そろそろ寝坊助を起こしますか?" puts "1, 部屋へ行って起こす" puts "2, 起こさずに仕事へ出かける" num = gets.to_i if num == 1 puts "誰を起こしますか?" sleeper = gets.chomp mother = Mother.new(sleeper) puts "どうやって起こしますか?" puts "1, フライパンをガンガン鳴らす(うるさいぞ!)" puts "2, カーテンを開けて朝の陽射しを食らわせる(眩しいぞ!)" puts "3, 布団をひっぺがす(寒いぞ!※あと思春期だとちょっと恥ずかしいかも)" plan = gets.to_i if plan == 1 mother.ding_frypan elsif plan == 2 mother.open_curtain elsif plan == 3 mother.strip_duvet else puts "ほんとは起こす気ないでしょ。ほな仕事いきましょ" Mother.go_job end elsif num == 2 Mother.go_job else puts "貴様ッッッ!さては母親ではないなッッッ!!!何奴!!?" end
- 投稿日:2020-10-27T11:50:52+09:00
【Rails】SameSiteとSecure属性の付与〜Railsのセキュリティ対策〜
はじめに
社内でcookieのセキュリティに関する勉強会があったので、学んだことをまとめておきます〜〜
Railsは優秀なフレームワークなので、そこそこのセキュリティ対策が標準装備されているんですよねえ。
セキュリティについてはあまり考えなくても、実装できてしまうんですよねえ。
良いことでもあり、悪いことでもありますねGoogleChrome80のリリース
2020年2月4日(現地時間)にGoogleChrome80が正式にリリースされました。
https://developers-jp.googleblog.com/2019/11/cookie-samesitenone-secure.html
今回のバージョンアップでデフォルトのCookieのSameSite属性がNone⇒Laxに変更されました。
またSameSite属性をNoneにする場合、Secure属性を付与しなければならない仕様になりました。???
なにそれ??私もピンと来ませんでしたし、よくわからない方もいるかも知れないので、ざっくり解説します。
SameSite属性
SameSite属性とは、CSRF(クロスサイトリクエストフォージェリ)というサイバー攻撃からユーザーを守るために、Cookieに付与される属性のことです。
安全のためのCookieのオプション設定みたいに考えておいてください。GoogleChrome80からこれのデフォルト値がNone⇒Laxに変更になったのです。
簡単に言うとセキュリティが強化されましたということです。
最近、Googleはセキュリティ対策に厳しいですからね〜SameSite属性は三段階にわかれています。
属性 内容 None ドメインをまたいでCookieの受け渡しが可能 Lax (GETでのリクエストのみ)ドメインをまたいでCookieの受け渡しが可能 Strict ドメインをまたいでCookieの受け渡しが不可 セキュリティのレベル的には
None < Lax < Strictですね。つまり、ドメインをまたいでCookieの受け渡しができるか?できないのか?という違いを設定する設定のことですね!
secure属性
Secure属性はHTTPS化していないCookieの動作を制御する属性のことです。
Secure属性が付与されているCookieはHTTPS通信の場合のみ送信できます。
要はCookieが盗まれにくくなります。GoogleChrome80からはSameSiteがNoneのときはSecure属性を付与しなければならない仕様に変更になりました。
つまり「SameSiteがNoneなんだろ?セキュリティー不安だからせめてSecure属性くらいつけておけよ〜」というGoogle様からのお達しということですね。
Railsでの設定
ではGoogleChrome80の仕様もSameSite属性・secure属性も理解したところで、Railsで設定をしてみましょう!
Gemfilegem 'rails_same_site_cookie'ターミナルbundle installはい。これだけです。
特に設定等もいりません。gem「rails_same_site_cookie」をインストールするだけです。
めちゃめちゃ簡単ですね。
自動的に全cookieにSameSite=None; Secure属性が追加してくれます。確認方法
確認方法も簡単です。
chromeの検証からApplicationをクリックして、使用中のCookieの中身を見ます。
secure属性にチェックが入っていて、SameSite属性がNoneになっていたらOKです。※ローカル環境では確認できないことがあるので注意してくださいね〜
おわりに
勉強会でとんでもないハッカーに出会ってしまったので、毎日震えながら開発しています
- 投稿日:2020-10-27T11:31:52+09:00
[Payjp] Payjp::InvalidRequestError No such tokenの解決法
概要
Payjpでcustomerを作成しようとした際、No such tokenというエラーを解決するのに時間を要したため、解決した流れを記載しておきます。
エラーの内容
上記のように、そのようなトークンはありませんと言われてしまいました。
- トークンはJs→Rails側に送信できている
- Completed 500 Internal Server Error
となっているため、サーバーサイド側のエラーだと思い、秘密鍵が合っているか等、色々試してみましたが解決できませんでした。
card.jsの記述
サーバーサイド側のエラーだと踏んでいたのですが、jsの記述も確認してみました。
card.jsconst pay = () => { Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY); const form = document.getElementById("charge-form"); form.addEventListener("submit", (e) => { e.preventDefault(); const formResult = document.getElementById("charge-form"); const formData = new FormData(formResult); const card = { number: formData.get("number"), cvc: formData.get("cvc"), exp_month: formData.get("exp_month"), exp_year: `20${formData.get("exp_year")}` }; Payjp.createToken(card, (status, response) => { if (status === 200) { const token = response.id; const renderDom = document.getElementById("charge-form"); const tokenObj = `<input value=${token}, type="hidden", name="card_token">`; renderDom.insertAdjacentHTML("beforeend", tokenObj); document.getElementById("card-number").removeAttribute("name"); document.getElementById("card-exp-month").removeAttribute("name"); document.getElementById("card-exp-year").removeAttribute("name"); document.getElementById("card-cvc").removeAttribute("name"); renderDom.submit(); renderDom.reset(); } }); }); }; window.addEventListener("load", pay);特におかしなところは無いように思えます・・・。
ある違和感
同じような記述で、jsを使って商品の合計金額(total_price)をサーバーサイドに送信するコードも書いていました。
sendTotalPrice.jsfunction sendTotalPrice() { const totalPriceDom = document.getElementById("cart-total-price") const totalPrice = parseInt(totalPriceDom.innerHTML); const renderDom = document.getElementById("charge-form"); const totalPriceObj = `<input value=${totalPrice}, type="hidden", name="total_price">`; renderDom.insertAdjacentHTML("beforeend", totalPriceObj); }; window.addEventListener('load', sendTotalPrice);ここでおかしいと感じたことがあります。
送信されたparamsのtotal_priceの中に
不要な " , " が入ってしまっています。原因はjs内の記述だった
トークンの値をフォームに含めるための記載に間違いがありました。
間違いconst tokenObj = `<input value=${token}, type="hidden", name="card_token">`;正しいconst tokenObj = `<input value=${token} type="hidden" name="card_token">`;value=${token}のあとのカンマ "," は不要でした!
勉強になったこと
Rails等のform_withなどでは属性を区切るためにカンマが必要ですが、HTML要素では属性を区切るカンマは不要ですね・・・。
同じような内容で悩まれている方がもしいらっしゃったら、参考になれば幸いです。
- 投稿日:2020-10-27T11:03:30+09:00
メソッド、Proc、Method クラスのオブジェクトの作り方とその実行
メソッド
メソッドの定義
メソッド定義
def メソッド名(引数) # 式 end
end
less メソッド定義Ruby 3 から使用可(予定)
def メソッド名(引数) = # 式メソッドの呼び出し
レシーバ.メソッド名(引数)Proc クラス
Proc クラスのオブジェクトの作り方
Proc
Proc.new{|引数| 式} proc{|引数| 式} Symbol または Hash または Method クラスのオブジェクト.to_proc[引数]lambda
lambda{|引数| 式} -> (引数){式}Proc オブジェクトの実行
レシーバ[引数] レシーバ.(引数) レシーバ.call(引数) レシーバ.yield(引数) レシーバ === # 引数Method クラス
Method クラスのオブジェクトの作り方
レシーバ.method(メソッド名の Symbol または String)メソッドの起動
レシーバ[変数] レシーバ.(変数){式} レシーバ.call(変数){式} レシーバ === 変数参考文献
- 投稿日:2020-10-27T10:46:29+09:00
【Ruby on Rails】確認ページ作成
目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina準備
今回はscaffoldを使用し、投稿の確認画面を作成します。
ターミナル$ rails g scaffold post body:string $ rails db:migratecontrollerの編集
下記を追加。
app/controllers/posts_controller.rbdef confirm @post = Post.new(post_params) endrouteの編集
下記を追加
config/routes.rbresources :posts post 'posts/confirm', to: 'posts#confirm', as: 'confirm'viewの編集
このままの状態であれば、new画面で投稿するとcreateアクションが実行され、保存されてしまいます。
したがって、new画面からはconfirmにparamsを飛ばすよう記述します。
<%= render 'form', post: @post %>
を削除し、下記のように記述します。app/viwes/posts/new.html.erb<h1>New Post</h1> <%= form_with(model: @post, local: true, url: confirm_path) do |form| %> <% if @post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= form.label :body %> <%= form.text_field :body %> </div> <div class="actions"> <%= form.submit %> </div> <% end %> <%= link_to 'Back', posts_path %>app/viwes/posts配下にconfirm.html.erbを作成します。
<%= @post.body %>
で投稿内容を表示し、
<%= form.hidden_field :body %>
でcreateアクションにparamsを渡しています。app/viwes/posts/confirm.html.erb<div>投稿内容確認<br><br> <%= @post.body %><br><br> </div> <%= form_with(model: @post, local: true) do |form| %> <div class="actions"> <%= form.hidden_field :body %> <%= form.submit %> </div> <% end %>まとめ
投稿画面での確認画面はあまりないとは思いますが、
新規登録画面ではよく見る表示だと思いますので、
会員登録等の機能を実装するなら必須の機能です。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-27T09:53:27+09:00
【Rails】アプリケーションを削除してみた
はじめに
テストで作成したミニアプリを削除てみました。備忘録もかねて記事に残します。
目次
1.手順
2.削除1. 手順
・データベースの削除
・フォルダ削除アプリを削除するには、ただフォルダを削除すれば良いと思っていました。
しかし、それではデータベースがの残ったままなので、不具合が起きる可能性があります。下記に参考にさせていただいた記事があります。アプリ以外もいろんなフォルダの削除方法を紹介されてるので、興味がある方は参考にしてみてください。
2. 削除
それでは削除して行きます〜
・データベースの削除
$ rails db:drop開発とテスト二つのデータベースが削除されれば成功です。
・フォルダ削除
$ cd .. $ rm [アプリ名]コマンドで削除可能ですが、ファインダーからゴミ箱に入れても削除できます。
以上です!
最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜参考
- 投稿日:2020-10-27T02:15:17+09:00
【Ruby】Rails/Sinatraを使わない場合のrbファイル実行時、i18nに`en is not a valid locale (I18n::InvalidLocale)'怒られる
背景
記事を書いた理由
公式サイトを見ればすぐに分かる何の事はない内容ですが、
ブログだったりQiitaのような、
わかりやすさ重視の非一次情報はなかなか見つからなかったので。状況
メタプログラミングRubyのMonetizeの例の項を実行していた時。
このような表示に。ruby $ ruby 202010270014.rb [WARNING] The default rounding mode will change from `ROUND_HALF_EVEN` to `ROUND_HALF_UP` in the next major release. Set it explicitly using `Money.rounding_mode=` to avoid potential problems. [DEPRECATION] You are using the default localization behaviour that will change in the next major release. Find out more - https://github.com/RubyMoney/money#deprecation Traceback (most recent call last): 10: from 202010270014.rb:5:in `<main>' 9: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money.rb:600:in `format' 8: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money/formatter.rb:232:in `to_s' 7: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money/formatter.rb:257:in `format_number' 6: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money/formatter.rb:333:in `format_whole_part' 5: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money/formatter.rb:238:in `thousands_separator' 4: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/money/formatter.rb:366:in `lookup' 3: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/locale_backend/legacy.rb:15:in `lookup' 2: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/money-6.13.8/lib/money/locale_backend/i18n.rb:19:in `lookup' 1: from /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/i18n-1.6.0/lib/i18n.rb:182:in `translate' /Users/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/i18n-1.6.0/lib/i18n.rb:326:in `enforce_available_locales!': :en is not a valid locale (I18n::InvalidLocale)ソースコード
エラー発生時
error.rbrequire "monetize" bargain_price = Monetize.from_numeric(99, "USD") p bargain_price.formatエラー解消時
success.rbrequire "monetize" I18n.load_path << Dir[File.expand_path("config/locales") + "/*.yml"] I18n.default_locale = :en # (note that `en` is already the default!) bargain_price = Monetize.from_numeric(99, "USD") p bargain_price.format公式リポジトリのREADMEより2,3行目を拝借。
上記のソースの書き換え+config/locales/en.ymlにymlファイルを設置。
その中身は公式リポジトリのREADMEそのままで以下。en.ymlen: test: "This is a test"実行時表示
ruby $ ruby 202010270014.rb [WARNING] The default rounding mode will change from `ROUND_HALF_EVEN` to `ROUND_HALF_UP` in the next major release. Set it explicitly using `Money.rounding_mode=` to avoid potential problems. [DEPRECATION] You are using the default localization behaviour that will change in the next major release. Find out more - https://github.com/RubyMoney/money#deprecation [DEPRECATION] You are using the default localization behaviour that will change in the next major release. Find out more - https://github.com/RubyMoney/money#deprecation "$99.00"WARNINGなんかは出ていますが、一応動作しました。
参考文献/サイト
- 投稿日:2020-10-27T02:15:05+09:00
RspecのテストでArgumentError: wrong number of arguments (given 2, expected 0)が出た時の対処法
はじめに
RSpecのテストを実行したときに
Failure/Error: post login_path, params: { session: { email: user.email, password: user.password } } ArgumentError: wrong number of arguments (given 2, expected 0)と出てエラー解決に時間がかかったので書いていきます。
エラー内容
このエラーは「呼び出し側の引数」(given 2)と2に対して「メソッド側の仮引数」(expect 0)で0ですよと言われています。何らかの理由で値にズレが生じているということです。
発生した原因
RSpecのコード内で
let!(:post) { create(:post, user: user) }という記述をしていて、post login_path, params: { session: { } }のpostがget,post,deleteなどのpostではなくてRSpecコード内のlet!(:post)を呼び出してしまっているから。
解決方法
先ほどあったコードの名前を変えてあげるだけです。
let!(:new_post) { create(:post, user: user) }参照
https://qiita.com/yo0917/items/20c165a3b06805bf2e37
最後に
すごい初歩的なミスかもしれませんがRSpec書きたての僕はすごい悩まされたので今後も頑張って解決していきたいです。
文章力も上げていきたいです。
- 投稿日:2020-10-27T02:15:05+09:00
RSpecのテストでArgumentError: wrong number of arguments (given 2, expected 0)が出た時の対処法
はじめに
RSpecのテストを実行したときに
Failure/Error: post login_path, params: { session: { email: user.email, password: user.password } } ArgumentError: wrong number of arguments (given 2, expected 0)と出てエラー解決に時間がかかったので書いていきます。
エラー内容
このエラーは「呼び出し側の引数」(given 2)と2に対して「メソッド側の仮引数」(expect 0)で0ですよと言われています。何らかの理由で値にズレが生じているということです。
発生した原因
RSpecのコード内で
let!(:post) { create(:post, user: user) }という記述をしていて、post login_path, params: { session: { } }のpostがget,post,deleteなどのpostではなくてRSpecコード内のlet!(:post)を呼び出してしまっているから。
解決方法
先ほどあったコードの名前を変えてあげるだけです。
let!(:new_post) { create(:post, user: user) }参照
https://qiita.com/yo0917/items/20c165a3b06805bf2e37
最後に
すごい初歩的なミスかもしれませんがRSpec書きたての僕はすごい悩まされたので今後も頑張って解決していきたいです。
文章力も上げていきたいです。
- 投稿日:2020-10-27T02:09:58+09:00
カレンダーから日付を選択するフォーム作成方法
- 投稿日:2020-10-27T01:28:39+09:00
演算子とは
演算子
プログラミングにおける値の計算や比較などに使用する記号のことです。
計算における代表的な演算子は+や-、比較における代表的な演算子は>や<があります。この簡単な記号である演算子を用いることで、計算や比較処理を瞬時に行ってくれます。
代数演算子
演算子の中でも計算を行うものは、代数演算子と呼ばれます。
Rubyで一般的な計算をする場合、以下の様な演算子が使えます。使い方は、普通の算数の計算と同じです。ただし、剰余の計算は馴染みがないので注意が必要です。
例えば、「17を5で割ったときの余り」を求めることができます。以下の例を見てください。
【例】irb# 足し算 irb(main):001:0> 1000 + 2000 => 3000 # 引き算 irb(main):002:0> 3000 - 1500 => 1500 # 掛け算 irb(main):003:0> 50 * 40 => 2000 # 割り算 irb(main):004:0> 600 / 15 => 40 # 剰余演算(5 ÷ 2をした余り) irb(main):005:0> 5 % 2 => 1irbで以下のコードを実行しましょう
1年は何時間か計算してみましょう。
irbirb(main):001:0> 24 * 365実行すると、一瞬で計算結果が表示されますね。
実際にやってみて下さいね!!まとめ
・演算子とは、プログラミングにおける値の計算や比較などに
使用する記号のこと。
・代数演算子とは、演算子に属し、その中でも計算を行うもの。以上。
- 投稿日:2020-10-27T01:26:00+09:00
【Rails6】jQuery導入・uncaught reference error $ is not definedエラーの解決法
開発環境
- Rails 6.0.0
- yarn 1.22.4
目次
1)jQuery導入
2)uncaught reference error $ is not definedエラーの解決法1) jQuery導入_箇条書き
1. yarn add jquery でjqueryを導入
2. environment.jsへ webpackの設定ファイルにjQueryを管理下に追加する記述を書く
3. application.jsへ jQueryを呼び出すための記述を書く
4. application.html.erbへ javascriptの呼び出しが記述されているか念の為確認1) jQuery導入_詳しく解説
1. yarn add jquery でjqueryを導入
ターミナル $ yarn init *補足:OSにHomebrewでyarnインストールをすでにされている場合は不要だと思います。 $ yarn add jquery*補足:私は"yarn add jquery"だけで問題ないのですが、他の方の記事を確認したところ、"yarn init"を先に入力するという説明もあったので、補足として記載させていただきます。『Homebrewでyarnインストール』についてはこちらの記事が参考になると思います。
*補足2:
gem 'jquery-rails'をGemfileへ記述する方法もありますが、Rails6からはyarn addが推奨されているらしいです。Webpackerで管理しているため、Node.jsのパッケージを利用しています。2. environment.js
app/config/webpack/environment.js//この記述内容をコピペ(もともとの記述は削除でOK) //これは、webpackの設定ファイルでjQueryを管理下に追加するための記述です。 const { environment } = require('@rails/webpacker') const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', jquery: 'jquery', }) ) module.exports = environment3. application.js
app/javascript/packs/application.js// 省略 require("@rails/ujs").start() require("turbolinks").start() //私はいつもコメントアウトします require("@rails/activestorage").start() require("channels") require('jquery') //ここを追記 // 省略*補足:turbolinksはキャッシュを積極的に利用するため、ページがロードされてから起こるイベントがうまく動かないことがあります。私はjavascriptを使う上で少し厄介だなという認識なので、コメントアウト。(キャッシュを利用するとページの読み込み時間は短縮されるんですけどね)
4. application.html.erb **念のために確認
app/view/layouts/application.html.erb<!-- tourbolinksを削除する場合こうなります --> <%= stylesheet_link_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application' %>ここまでがJqueryを導入するまでの一連の流れです。
2) $ is not definedエラーの解決法
$がnot defined(定義されていない)ということは、jQueryがうまく入れることができていないということなので、jQuery導入で説明した4ステップを確認すれば、解決するのではないかなと思います。
1. yarn add jquery でjqueryを導入
2. environment.jsへ webpackの設定ファイルにjQueryを管理下に追加する記述を書く
3. application.jsへ jQueryを呼び出すための記述を書く
4. application.html.erbへ javascriptの呼び出しが記述されているか念の為確認以上です。
- 投稿日:2020-10-27T00:51:56+09:00
Rails学習 2日目その2
Ruby on Rails5速習実践ガイド chapter5
5-4 本章で記述するテストの種類(RSpec)
テストの一番外枠に位置しているシステムテスト(System Test)が重要
RSpecとはSystemTestが行われるソフトみたいなもの
systemtestの中ではcapybaraというソフトがまるでウェブアプリケーションを実行しているかのように動き、その動きの中でシステムエラーが無いかなどを見てくれる。5-7 FactoryBotでテストデータを作成できるように準備する
まずはじめにデータベースを使ってテストをする時にはテスト用のデータがないと話にならない。FactoryBotでテストデータを作成し、そこからテストという流れになっている。ここではFactoryBotでの具体的なデータの書き方を見てみる。テストを実行するために必要な具体的な工程は2つある
1.FactoryBotでデータを作成するためのテンプレートを作成する。
2.SystemSepcの適切なbeforeなどで、FactoryBotのテンプレートを利用してテスト用データベースにテストデータを投入する。spec/factories/users.rbFactoryBot.define do factory :user do #① name {'テストユーザー'} email {'test@example.com'} password {'password'} end endfactoryというメソッドを書きその中にユーザー情報(仮)の値を入れた。これがテスト用のデータになる。
①factory:〇〇 do(今回はuser)この〇〇の部分がこのファクトリーの名前となり呼び出す時に使う名前となる。基本は作ったデータのテーブルに対応するクラス(userテーブルに対応するのはuserクラス)の名前を使う。そうすることによってクラス名もfactoryメソッド名も両方をまとめることができる。
しかしどうしてもクラス名とメソッド名が違う物を用いたい場合はfactory :admin_user, class: User do上記のようにfactory :ファクトリー名, class:クラス名 doというようにしてもいい
テスト用のTaskデータも作成する
spec/factories/tasks.rbFactoryBot.define do factory :task do name {'テストを書く'} description {'RSpec & Capybara & FactoryBotを準備する'} user #① end end①上記のuserはtaskとuserを関連付けるためのもの(この作ったタスクはどのユーザーのものなのかをここに書く)
5-8 タスクの一覧表示機能のSystemSpec
上記では
1.FactoryBotでデータを作成するためのテンプレートを作成する。
2.SystemSepcの適切なbeforeなどで、FactoryBotのテンプレートを利用してテスト用データベースにテストデータを投入する。
の1番を行ってきた。次に2番のテストをSystemSpecを用いて行う。今回は一覧画面に移ったら作成済みのタスクが表示されている
といった動作が正しく動くかテストコードを書いて確認してみる。
まず確認するためには動くようのテストコードを書かなければならない。テストコードは①ユーザーAを作成しておく(準備)
②作成者がユーザーAであるタスクを作成しておく(準備)
③ユーザーAでブラウザからログインする(準備)
④ユーザーAの作成したタスクの名称が画面上に表示されていることを確認(実行)この4つの工程をテストコードで書いていく
①ユーザーAを作成しておく(準備)
spec/system/tasks_spec.rbuser_a = FactoryBot.create(:user, name: 'ユーザー名', email:'a@example.com')userという名前のファクトリーを引っ張り出してきてその情報をuser_aとしている.
後ろについているnameやemailを書くことによって内容を変更しユーザーAだけの情報が作られる(なおpasswordなどの変更していない部分はfactoryメソッドを作った時に設定した値になる)②作成者がユーザーAであるタスクを作成しておく(準備)
spec/system/tasks_spec.rbFactoryBot.create(:task, name: '最初のタスク', user:user_a)user:user_aと書くことでこのタスクはuser_aが書いたということになる。
③ユーザーAでブラウザからログインする(準備)
ログインするにはA.ログイン画面にいく
B.メールアドレスを入力する
C.パスワードを入力する
D.「ログインする」ボタンを押すという動作が必要。
A.ログイン画面にいくにはvisit login_pathという書き方で実行できる(visit URL)
spec/system/tasks_spec.rbvisit login_pathB.メールアドレスを入力する、C.パスワードを入力するにはfill_inメソッドを使う
spec/system/tasks_spec.rbfill_in'メールアドレス', with: 'a@example.com' fill_in'パスワード', with: 'password'D.「ログインする」ボタンを押すにはclick_buttonメソッドを使う
spec/system/tasks_spec.rbclick_button'ログインする'③をまとめると
spec/system/tasks_spec.rbvisit login_path fill_in'メールアドレス', with: 'a@example.com' fill_in'パスワード', with: 'password' click_button'ログインする'このようになる。
④ユーザーAの作成したタスクの名称が画面上に表示されていることを確認(実行)
確認するにはRSpec独自の書き方で
expect(page).to have_content '最初のタスク'expect(page).to→画面に期待するよ
have_content '最初のタスク'→最初のタスクというコンテンツがあるかどうか
という意味になる以上の操作を1つのコードにまとめてみる
①②③は準備のためのコードなのでbefore
④は実行のためのコードなのでitを使い記入するspec/system/tasks_spec.rbrequire 'rails_helper' describe 'タスク管理機能',type:system do #一番大枠のdescribeにはtype:systemをつける describe '一覧表示機能' do before do user_a = FactoryBot.create(:user, name: 'ユーザー名', email:'a@example.com') FactoryBot.create(:task, name: '最初のタスク', user:user_a) end context'ユーザーAがログインしているとき' do before do visit login_path fill_in'メールアドレス', with: 'a@example.com' fill_in'パスワード', with: 'password' click_button'ログインする' end it'ユーザーAが作成したタスクが表示される' do expect(page).to have_content '最初のタスク' end end end endPSpecの概要
5-10 beforeを利用した共通化
ユーザーAだけでなくユーザーBがログインしているパターンを作る
spec/system/tasks_spec.rbrequire 'rails_helper' describe 'タスク管理機能',type:system do #一番大枠のdescribeにはtype:systemをつける describe '一覧表示機能' do before do user_a = FactoryBot.create(:user, name: 'ユーザー名', email:'a@example.com') FactoryBot.create(:task, name: '最初のタスク', user:user_a) end context'ユーザーAがログインしているとき' do before do visit login_path fill_in'メールアドレス', with: 'a@example.com' fill_in'パスワード', with: 'password' click_button'ログインする' end it'ユーザーAが作成したタスクが表示される' do expect(page).to have_no_content '最初のタスク' end end context'ユーザーBがログインしているとき' do before do visit login_path fill_in'メールアドレス', with: 'b@example.com' fill_in'パスワード', with: 'password' click_button'ログインする' end it'ユーザーAが作成したタスクが表示されない' do expect(page).to have_no_content '最初のタスク' end end end endvisit login_path
fill_in'メールアドレス', with: 'a@example.com'
fill_in'パスワード', with: 'password'
click_button'ログインする'
が2つあってわかりにくくなる。なのでこれを1つにまとめる。spec/system/tasks_spec.rbrequire 'rails_helper' describe 'タスク管理機能',type:system do #一番大枠のdescribeにはtype:systemをつける describe '一覧表示機能' do before do user_a = FactoryBot.create(:user, name: 'ユーザー名', email:'a@example.com') FactoryBot.create(:task, name: '最初のタスク', user:user_a) visit login_path fill_in'メールアドレス', with: 'a@example.com' fill_in'パスワード', with: 'password' click_button'ログインする' end context'ユーザーAがログインしているとき' do it'ユーザーAが作成したタスクが表示される' do expect(page).to have_content '最初のタスク' end end context'ユーザーBがログインしているとき' do before do FactoryBot.create(:user, name: 'ユーザー名', email:'a@example.com') end it'ユーザーAが作成したタスクが表示されない' do expect(page).to have_no_content '最初のタスク' end end end endユーザーAがログインしているときは上のitを実行し、ユーザーBがログインしているときは下のitを実行する。
5-11 letを利用した共通化
FactoryBotで作ったデータをletを使って変数みたいに扱うことができる。
spec/system/tasks_spec.rbrequire 'rails_helper' describe 'タスク管理機能',type:system do #一番大枠のdescribeにはtype:systemをつける describe '一覧表示機能' do let(:user_a){FactoryBot,create(:user, name:'ユーザーA', email: 'a@example.com')} #ユーザーAを作ったパターン let(:user_b){FactoryBot,create(:user, name:'ユーザーB', email: 'b@example.com')} #ユーザーBを作ったパターン before do FactoryBot.create(:task, name: '最初のタスク', user:user_a) visit login_path fill_in'メールアドレス', with: login_user.email #ログインするのがAかBかわからないのでどちらでも行けるようにする fill_in'パスワード', with: login_user.password #ログインするのがAかBかわからないのでどちらでも行けるようにする click_button'ログインする' end context'ユーザーAがログインしているとき' do let(:login_user){user_a} #上で定義したユーザーAの情報を引き出す it'ユーザーAが作成したタスクが表示される' do expect(page).to have_content '最初のタスク' end end context'ユーザーBがログインしているとき' do let(:login_user){user_b} #上で定義したユーザーBの情報を引き出す it'ユーザーAが作成したタスクが表示されない' do expect(page).to have_no_content '最初のタスク' end end end end5-13 shared_exampleを利用する
同じitの結果を様々なdescribeで実行する時にまとめる方法
#it操作をshared_example_forに書く shared_example_for 'ユーザーAが作成したタスクが表示される' do it {expect(page).to have_content '最初のタスク'} end #it_behaves_likeと書くだけでit操作を一回一回書かなくていいようになる it_behaves_like 'ユーザーAが作成したタスクが表示される'
- 投稿日:2020-10-27T00:07:01+09:00
Herokuへデプロイする手順
Herokuへデプロイする手順
ターミナルbrew tap heroku/brew && brew install herokuターミナルheroku --versionターミナル# Herokuへログインするためのコマンド % heroku login --interactive => Enter your Heroku credentials. # メールアドレスを入力し、エンターキーを押す => Email: # パスワードを入力して、エンターキーを押す => Password:Gemfile# ファイルの一番下の行に追記する group :production do gem 'rails_12factor' endターミナル# Gemをインストール % bundle installターミナル% git add . % git commit -m "gem rails_12factorの追加"ターミナル% heroku create アプリケーション名ターミナル% git config --list | grep herokuターミナル% heroku addons:add cleardb Creating cleardb on ⬢ アプリケーション名... free Created cleardb-vertical-00000 as CLEARDB_DATABASE_URL Use heroku addons:docs cleardb to view documentationターミナル% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`ターミナル% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5} # 以下、コマンドの実行結果 Setting DATABASE_URL and restarting ⬢ アプリケーション名... done, v◯◯ DATABASE_URL: mysql2://000000000000:0aa0000@us-cdbr-east-02.cleardb.com/heroku_aaa00000000?reconnect=trueターミナル% EDITOR="vi" bin/rails credentials:editターミナル% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`ターミナル% heroku configターミナル% git push heroku masterターミナル% heroku run rails db:migrate公開を確認
ターミナル% heroku apps:info ===ajax-app-123456 Addons: cleardb:ignite Auto Cert Mgmt: false Dynos: web: 1 Git URL: https://git.heroku.com/アプリケーション名.git Owner: sample@sample.com Region: us Repo Size: 165 KB Slug Size: 56 MB Stack: heroku-18 Web URL: https:/アプリケーション名.herokuapp.com/現場からは以上です!