- 投稿日:2020-10-27T23:47:18+09:00
忘れないうちに、フリマアプリの機能とポイントまとめ
はじめに
作成していたフリマアプリのようなものが一段落したので、まとめておく。完全に自分用。
実装した機能
ユーザー管理
deviseというGemを使用。
RSpecを用いてテストコードを記述。Fakerでテスト用データをFactoryBotに記述。
GimeiというGem、日本語版のFakerを使用。
正規表現。
エラーエラーハンドリングをrenderメソッドを使って表示。商品の出品機能
ActiveHash導入。
ActiveStorageを導入して、画像を保存できるように。
Fakerの日本語対応を使って、テストコード記述。
JSを使ってブラウザ上でリアルタイムに利益等を計算。商品の一覧表示
if文の条件文にexists?メソッドで、テーブルにデータが無いときと処理を分岐。
商品の詳細表示機能
ActiveHashのnameを表示(@変数名.model名.name名)
商品の削除機能
before_actionで同じ処理をまとめる。
商品の編集機能
newアクションと同じフォームにまとめる。
商品購入機能
商品と購入者の組み合わせをパラメーターから取ってくるため、mergeメソッドを使う。
APIの導入(PAY.JP)を使ってクレジットカード決済の導入。JSでtokenをレスポンス。
tokenをmerge。
購入済みにsold outを表示。
<% if @item.purchase %>
を使って条件分岐。
- 投稿日:2020-10-27T23:31:00+09:00
【Rails】音声投稿機能 ~Cloudinary, CarrierWave
はじめに
この記事では音声ファイルの投稿機能を実装します。
Cloudinary(外部ストレージ)を使います。
フリープランで月1GBまで利用できます。前提
Tweetモデルにて、テキストでの投稿機能は一通りできている
まず、、、
Cloudinaryにアカウントを登録してください!
メルアドにて本登録も忘れずに!上記のアカウント取得後、以下の作業に入ってください!
audioカラムの追加
tweetsテーブルにstring型のaudioカラムを追加します。
ターミナル$ rails generate migration AddAudioToTweets audio:stringターミナル$ rails db:migrateこのaudioカラムは音声ファイルのURL(住所)が書かれます。音声ファイル自体は別の場所に保存されます。
Index.html.erb
audioファイルを再生するコードを書きます
app/views/tweets/index.html.erb<% @tweets.each do |t| %> <%= audio_tag t.audio_url, :controls => true if t.audio? %> <% end %>
:controls => true
はコントローラパネルを表示します。
また、audio_tagには以下のオプションがあります。
:autoplay
自動再生
:loop
ループ再生ストロングパラメーター
audioパラメータを受け取れるようにストロングパラメーターに記述します。
tweets_controller.rb# 割愛 private def tweet_params params.require(:tweet).permit(:body, :audio) endnew.html.erb
fileをuploadするコードを書きます。
app/views/tweets/new.html.erb<%= form_for @tweet do |f| %> <div class="field"> <%= f.label :audio %> <%= f.file_field :audio %> </div> <%= f.submit "Tweetする" %> <% end %>gemの追加
今回はcloudinaryと、carrierwaveというgemを使っていきます。Gemfileの一番下に以下を追加しましょう。
Gemfilegem 'carrierwave' gem 'cloudinary'ターミナル$ bundle installそれぞれのgemを簡単に説明すると
carrierwave : railsにてファイルのuploadができるようにするためのgem
cloudinary : 外部ストレージサービスのcloudinaryが利用できるようにするためのgemアップローダーの作成
CarrierWaveのジェネレーターでアップローダーを作成します。以下のコマンドをターミナルに打ち込みましょう。
ターミナル$ rails g uploader Audioモデルの修正
app/models/tweet.rbを以下のように修正します。
app/models/tweet.rbclass Tweet < ApplicationRecord # 追記ここから mount_uploader :audio, AudioUploader # 追記ここまで end
mount_uploader :audio, AudioUploader
は音声ファイルを指定の場所に保存することを表します。次に保存場所を指定するアップローダの設定です。
app/uploaders/image_uploader.rbの6~8行目を変更しましょう。
app/uploaders/audio_uploader.rb# Choose what kind of storage to use for this uploader: storage :file # storage :fog上記を下図のように変えます。
app/uploader/audio_uploader.rb# Choose what kind of storage to use for this uploader: if Rails.env.production? include Cloudinary::CarrierWave CarrierWave.configure do |config| config.cache_storage = :file end else storage :file end # storage :fogcloudinaryは外部のストレージサービスです。本番環境(リリース後=production)ではcloudinaryに画像が保存され、それ以外(開発環境=ローカル)では自分のpcに保存されます。(publicフォルダー内に保存されます)
APIキーの非公開
Cloudinaryの各アカウントには「Cloud name」、「API Key」、「API Secret」が付与されています。
Cloudinaryのアカウントを外部に漏らさないためにセキュリティを強化します。
ここではdotenv-railsというgemを使っていきます。Gemfileの一番下に以下を追加しましょう。
Gemfilegem 'dotenv-rails'ターミナル$ bundle installと打ち込んでインストールします。
次に
.env
というファイルをアプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)に自分で作成します。
以下の図のようになっていればオッケーです。
※vendorフォルダーの中ではないので注意してください。次に作成した
.env
ファイルに以下を入力します。.envCLOUD_NAME=q0w9e8r7t6yu5 #←この値は人によって違います!! CLOUDINARY_API_KEY=123456789012345 #←この値は人によって違います!! CLOUDINARY_API_SECRET=1a2s3d4f5g6h7j8k9l0a1s2d4f5g6h1q #←この値は人によって違います!!ここで「=」の後のそれぞれの値は先ほどのCloudinaryのマイページで取得したキーに書き換えてください(自分が取得したキーは絶対他言しないように!!また数字は個々人によって変わります)。
また、書き換える際は、コメントアウト部分を削除してください!最後に隠しておきたいデータを定義した.envファイルを公開しないようにします。
.gitignore
に下記を追加します。
※もし.gitignore
ファイルがない場合はアプリケーションディレクトリーにて作りましょう!.gitignore# 省略 /.envこれでOKです!
APIキーの利用
最後の手順です!
まずはconfigフォルダにcloudinary.ymlファイルを作成してください。config/cloudinary.ymlに以下のようにそのままコピペしてください。
config/cloudinary.ymldevelopment: cloud_name: <%= ENV['CLOUD_NAME'] %> api_key: <%= ENV['CLOUDINARY_API_KEY'] %> api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> enhance_image_tag: true static_file_support: false production: cloud_name: <%= ENV['CLOUD_NAME'] %> api_key: <%= ENV['CLOUDINARY_API_KEY'] %> api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> enhance_image_tag: true static_file_support: false test: cloud_name: <%= ENV['CLOUD_NAME'] %> api_key: <%= ENV['CLOUDINARY_API_KEY'] %> api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %> enhance_image_tag: true static_file_support: falseこれでAPIキーを非公開にしたまま利用することができました。
これにて、音声ファイルの投稿はできるようになりました。お疲れ様です(^^)/
公式ドキュメント
- 投稿日: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-27T21:28:03+09:00
[Rspec] Rspecを導入してモデルの単体テストコードを書くまでの流れ
今回はテストコードを書く時にRspecを導入する手順を忘備録代わりにメモします。
Gem導入
テストで使うgemを3種類導入します。
group :development, :test do ~ end
の処理内に記述します。Gemfilegroup :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails gem 'factory_bot_rails' gem 'faker' end記述したら
bundle install
して、ローカルサーバーを再起動します。Rspecに必要なファイルをインストールする
ターミナル% rails g rspec:installテスト結果のログを可視化する
.rspec--require spec_helper --format documentation # => 追記エラーメッセージを英語に設定(任意)
テストのエラーメッセージを英語で表示させたい場合は設定します。
RSpec.configure do |config|
の上に追記。spec/rails_helper.rb# 中略 I18n.locale = "en" RSpec.configure do |config| # 中略FactoryBotのファイル作成
- specディレクトリの中に、
factories
ディレクトリを作成します。- そして、その中にテスト用のFactoryBotを生成するファイルを作成する。
- 名前は
モデル名s.rb
。今回はuserモデルのテストコードを書きたいのでusers.rb
とします。ユーザー情報をFactoryBotで生成
spec/factories/users.rbFactoryBot.define do factory :user do name {Faker::Name} email {Faker::Internet.free_email} password = Faker::Internet.password(min_length: 6) password {password} password_confirmation {password} end endFactoryBotが生成できていることを確認
ターミナル(コンソール)pry(main)> FactoryBot.create(:user)エラーが発生した時は
- 私は上記のコマンドでエラーが発生しました。その時は、Springが裏で動いていることが原因みたいなので
spring stop
コマンドでSpringを停止させます。Spring stopped.
と出れば正常にSpringが停止できています。- そして再度コンソールで
FactoryBot.create(:user)
とコマンドを打って生成を確かめましょう。ターミナル`# exitでコンソール終了 % spring stopテストコードを記述するファイルを準備
- 下記のコマンドで
spec/models/user_spec.rb
というファイルが生成されます。:ターミナル % rails g rspec:model user
テストコード記述
こんな感じでどんどんテストコードを書いていきます。
spec/models/user_spec.rbrequire 'rails_helper' RSpec.describe User, type: :model do pending "add some examples to (or delete) #{__FILE__}"# => 元々の記述は削除 describe 'ユーザー新規登録' do before do @user = FactoryBot.build(:user) end it "name, email, password, password_confirmationが全て入力されれば保存されること" do expect(@user).to be_valid end end endテストコードを実行する時は
以下のコードを実行します。
ターミナル% bundle exec rspec spec/models/user_spec.rbFakerの書き方について参考サイト
https://rubydoc.info/gems/faker/1.3.0/frames
http://railscasts.com/episodes/126-populating-a-database
https://github.com/takeyuweb/trygems/blob/master/try-faker/faker.mdFaker::Japanese
https://github.com/tily/ruby-faker-japanese
- 投稿日: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:49:53+09:00
【Rails】form_withの注意点
順番が逆だと動作しない。
routes.rbresources :prototypes do resources :comments, only:[:create] endprototype_comments POST /prototypes/:prototype_id/comments(.:format) comments#create以上の条件では、form_withは以下の通りとなる。
<%= form_with model: [@prototype, @comment], local: true do |f| %>[@親ルート, @子ルート]になっており、[@prototype, @comment]を逆に書いてしまうとルートが存在しなくなってしまい、エラーとなる。
- 投稿日:2020-10-27T18:48:16+09:00
Spree::Taxonomyのカラムを解説
solidus使おうとすると、初心者はイメージ掴みにくいですよね。
この記事を読まれていると言うことは少し全体像が掴めて、「Spree::Taxon」にはどう言ったカラムが存在するんだ?」と言うところなのかなと思います。
そこで今回は「Spree::Taxon」内のカラムについて簡潔に紹介と説明をしていきます。Solidusのバージョン
solidus 2.0.9
カラムの紹介と説明
Spree::Taxonomyのid=1をのぞいてみましょう。
それではここにあるカラムについて説明します。id
id。
name
分類(taxonomy)名。
create_at
分類(taxonomy)が作られた時間。
update_at
分類(taxonomy)が更新された時間。
position
Taxonomyリスト中におけるPositionが設定される。
例えば、2つのTaxonomyがある場合、1または2となる。<関連情報>
Spree::Productのカラムを解説
https://qiita.com/roooll12/items/92b370741a53c8dd268cSpree::Taxonのカラムを解説
https://qiita.com/roooll12/items/6f1dda6c5f4ea16e0c4c駆け出しsolidus開発者にとってSpree::Taxonモデルを理解する糧になれば幸いです!
- 投稿日:2020-10-27T18:25:39+09:00
Rails モデルとテーブルの命名規則
- 投稿日: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-27T17:34:00+09:00
"Rails6"で "assets" "turbolinks" を削除する。
この記事の目的
この記事はRails6でWebpackerを使用し
assets pipeline
とturbolinks
を削除するまでの手順内容を記録し記事にしたものです。
- 開発内容の確認と復習
- 開発手順の忘備録
- 少しでも他の方の参考になれば
と思い、本記事を作成行いました。
なせassetsを削除しようと思ったのか?
Rails6 以降は標準のモジュールバンドラとして
Webpacker
が使われるようになりました。
依然としてrails new 時での assetsは健在ですが、
assetsに初期インストール時にはjavascriptのディレクトリはRails6では最初に作成されなくなっています。
また、sprocketsのgem更新は滞っていますし、新しいJavaScriptのES2015
React,Vueなどのフロントエンドフレームワーク等が主流になる中で
assetsとwebpackerの2重体制から脱却して
webpackerのみで開発を経験しておきたいと思い実行しました。開発環境
今回は私が以前書いた記事のDocker-composeで開発を行っております。
環境構築の詳細はQiitaの記事
"Docker-compose" で "Rails6" の安定的な開発環境構築マニュアル
をご確認ください。
1.assetsの削除
Webpackerが標準となったRails6ではassetsを使用せずにapp/javascript配下に集約し
assetsを削除したいと思います。app/assetsディレクトリを削除する
2. application.jsにて読み込みを記載する
Ajaxなどで使うjqueryとフロントエンドのフレームワークとしてbootstrapを読み込んで、
さらに、application.scssも読み込むことで、webpackerでjsとcssを一元管理します。app/javascript/packs/application.jsrequire("jquery") require("bootstrap") import "../stylesheets/application.scss"3.javascriptディレクトリ配下にstylesheetsのディレクトリとapplication.scssのファイル作成
application.scssにbootstrapの読み込みを記載しておきます。
app/javascript/stylesheets/application.scss@import "~bootstrap/scss/bootstrap";4.layouts.scssの変更
assetsを使わなくなったので、layoutsをstylesheet_pack_tagに変更を行います。
またターボリンクは使わないので、下記のコードに変更となります。app/views/layouts/application.html.erb<%= stylesheet_pack_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application' %>5.turbolinks削除
Rails6ではyarnとgemの両方で削除しないと完全に削除できない模様。
yarn
で削除yarn remove turbolinks
Gemfile
で削除gem 'turbolinks', '~> 5'bundle installさらに app/javascript/packs/application.jsから"turbolinks"を削除します。
6. config/webpack/environment.jsの編集
AjaxでjQueryで$を使うために下記の記述を行います。
config/webpack/environment.jsconst { environment } = require('@rails/webpacker') const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery/src/jquery', jQuery: 'jquery/src/jquery' }) ) module.exports = environment7.webpacker.ymlの編集
dockerを使っているので、localhostだとエラーが発生します。
下記の3カ所を修正し対応します。config/webpacker.ymlcheck_yarn_integrity: false host: 0.0.0.0 public: 0.0.0.0:30358.docker-compose.yml にポート追加
8.で行った修正の為にポート追加を行います。
- "3035:3035"9.sprocketsのバージョンを下げる
Gemfileのsprocketsのバージョンを下げないと完全にassetsを削除できない模様。
https://github.com/rails/sprockets/issues/643gemfileを変更する
gem 'sprockets', '~> 3.7.2'bundle update sprockets10.foremanの導入
foreman は、Procfile を読み込み、複数のプロセスを管理できるツール。
アプリケーションで管理するプロセスを Procfile に記述し、
アプリケーションルートに配置する事で対応します。
参考URL:foremangem 'foreman'Procfile.devweb: bundle exec rails s -b 0.0.0.0 -p 3000 webpacker: bin/webpack-dev-serverbundle install しておきます。
bundle installbashファイルもforemanに合わせて修正しました。
qs.bashrails_server() { compose_stop $app rm_pids $dc run $rm --service-ports $app bundle exec foreman start -f Procfile.dev }上記で
assets
turbolinks
の削除は完了したはずです。最後に
できればAjaxもJQueryから脱却したかったのですが、
まだ学習不足で置き換えはまだできておりません。
学習完了すれば、最終的にES2015に移行できたと言えると思います。初心者ゆえに作業内容や間違いがあるかもしれません。
お気づきの点があればお知らせ頂けましたら幸いです。
- 投稿日:2020-10-27T17:22:13+09:00
楽天商品検索APIを用いた実装をしてみる(簡単)
はじめに
Rails 6.0.3.4
今回は楽天商品検索APIを使った超シンプルな検索アプリ実装の手順を記録したいと思います。
おそらくわかりやすいかは置いておいて、1番シンプルなやり方ではないかな・・・?
と勝手に思っています。今回、エラーハンドリングは省きます。https://webservice.rakuten.co.jp/
上記から登録をして、アプリケーションIDを取得しておきましょう。itemsコントローラー作成
rails g controller items search
このコマンドをターミナルで入力すると、コントローラーやビュー(search.html.erb)、
更にルーティングの記述もしてくれます(ルーティングは、お好みで修正してください。)ビューを記述する
<h2 class="product-subtitle-explain">商品を検索してみよう!</h2> <%= form_with url:product_search_path, method: :get, local: true do |f| %> <%= f.text_field :keyword, placeholder: "検索キーワードを入力してください", autocomplete: 'off' %> <%= f.submit "検索" , :name => nil%> <% end %> <h2>検索結果</h2> <%= render partial: 'item_list' %>大体このような感じでしょうか。
特に保存するものもないので、form_withにはどのアクションに飛ばすか、urlを書いておきます。
:keyword
として、検索ワードを:keywordに格納します。←大事!
placeholder: "検索キーワードを入力してください"
として、フォームに例として文字を置いておきました。また、
autocomplete: 'off'
で、フォームの自動補完を無効にしてあります。ここで最後に注目していただきたいのですが、
<%= render partial: 'product_list' %>
として、検索結果を表示する箇所は別のビューファイルに飛ばしています。
なのでここで、app/views/itemに、
_item.list.erb
を作成します。さっき作ったsearch.html.erbと同じ場所ですね。次はrender先の_item.list.erbに、
結果を表示させる記述をしていきます。<% @items.first(10).each do |item| %> <img src="<%= item['smallImageUrls'][0] %>"> <a href="<%= item['itemUrl']%>" target="_blank"><%= item['itemName']%></a> <%= item['itemPrice'] %>円 <% end %>上から見ていくと、まず
<% @items.first(10).each do |item| %>★<%end%>
として、★の中に、商品の何を写したいのかを記述しました。
.first(10)
とすることで、検索に引っかかった最初の10アイテムを表示しています。
@items
はこのあとsearchコントローラーで定義していきます!(今ビューを見てもエラーになります)
item['smallImageUrls'][0]
アイテムの1つ目の画像を小さなサイズで取得しています。
item['itemUrl']
アイテムの詳細に行けるURLを取得しています。
target="_blank"
アイテムをクリックしたときに、別タブを開いて楽天の商品詳細ページに行く設定にしてます
item['itemName']
アイテムの名前を取得しています。
['itemPrice']
アイテムの値段を取得しています。
他にもアイテムに関する様々な情報を取得することができます。↓
https://webservice.rakuten.co.jp/api/ichibaitemsearch/コントローラー記述
https://webservice.rakuten.co.jp/sdk/ruby.html
を基に実装していきます。gem 'rakuten_web_service'をgemファイルに付け加えて、
bundle install
して
ターミナルを再起動させてください。
ここからitemsコントローラーの記述に入ります。class ProductController < ApplicationController require 'rakuten_web_service' def search if params[:keyword].present? @items = RakutenWebService::Ichiba::Item.search(keyword: params[:keyword]) else render :search end end end
params[:keyword]
は、search.html.erbの入力フォームでキーワードを格納してあります。
paramsで[:keyword]をチェックし、@itemsに格納しています。
RakutenWebService::Ichiba::Item.search
は決まり文句です。詳しくは
https://webservice.rakuten.co.jp/sdk/ruby.html
を見てみてください。アプリケーションIDの設定
config/initialize下に、rukuten.rbを作成してください。
その中にアプリケーションIDを記述していきます
タイミングによっては記述方法が異なるので、公式も見るようにしてください。RakutenWebService.configure do |c| c.application_id = '*******************' c.affiliate_id = '*******************' ←こちらは任意 end環境変数を使うときには以下になります
RakutenWebService.configure do |c| c.application_id = ENV['RWS_APPLICATION_ID'] c.affiliate_id = ENV["RWS_AFFILIATION_ID"] endうまくいった後は、本番環境でも環境変数を設定してください。
HTML・CSSで整えた後ですが、おそらくこのような感じになるのではないかなと思います
- 投稿日:2020-10-27T16:31:47+09:00
【Rails / RSpec】 Modelテストを書く(Shoulda Matchers・FactoryBot 使用)
はじめに
テストを全く記述したことがない状態から RSpec を実際に記述しながら学びました。理解した内容を実際に記述したコードとともに記事に残したいと思います。
※RSpec 初心者です。誤り、ご指摘などございましたらコメントいただければ非常にありがたいです。
前提
- Usersテーブル
- カラム:
email: string
とpassword: string
のみ- Booksテーブルと1対多の関連付けがされている
- テストデータの生成には Gem
FactoryBot
を使用- テストには簡単に記述できる Gem
Shoulda Matchers
を使用
Shoulda Matchers
を使うと何行も記述しないとできなかったテストが1行で書けてしまいます。何が行われているかわからない部分もありますが、今回記述した内容の他にも便利な構文が用意されておりますので、興味のある方は参考サイトからぜひ確認してみることをお勧めします。参考サイト
- 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
- 使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」
- Shoulda Matchers
- FactoryBot(FactoryGirl)チートシート
- 【RSpec】で書く「Rails Tutorial 6章」のテスト
非常にわかりやすく大変参考にさせていただきました!
ありがとうございました!Model
app/models/user.rbclass User < ApplicationRecord has_many :books # booksと1対多の関連付け has_secure_password before_save { email.downcase! } validates :email, presence: true, length: { maximum: 255 }, format: { with: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i }, uniqueness: { case_sensitive: false } validates :password, presence: true, length: { minimum: 6 } endテスト
合計9つのテストを行っている
ファイル全体
spec/models/user_spec.rb# rails_helperファイルを読み込み require 'rails_helper' # Userモデルのテストなので User, type: :model としている RSpec.describe User, type: :model do describe 'has_many' do # has_many :books のテスト it { should have_many(:books) } end describe 'has_secure_password' do # has_secure_password のテスト it { should have_secure_password } end describe 'validation' do context 'email' do # FactoryBot でテストデータを作成 let(:user) { create(:user) } let(:upcase_email_user) { build(:user, :upcase_email) } # presence: true のテスト it { should validate_presence_of(:email) } # length: { maximum: 255 } のテスト it { should validate_length_of(:email).is_at_most(255) } # uniqueness: { case_sensitive: false } のテスト it 'emailの重複保存を許容しないこと' do duplicate_user = user.dup duplicate_user.email = user.email.upcase expect(duplicate_user).to be_invalid end # format: { with: XXXXX } のテスト it '指定formatに合わないemailを許容しないこと' do invalid_emails = %w[user@foo,com user_at_foo.org example.user@foo.foo@bar_baz.com foo@bar+baz.com foo@bar..com] invalid_emails.each do |invalid_email| user.email = invalid_email expect(user).to be_invalid end end # before_save { email.downcase! } のテスト it 'downcase!が正常に動作していること' do upcase_email_user.save! expect(upcase_email_user.email).to eq 'test@test.com' end end context 'password' do # presence: true のテスト it { should validate_presence_of(:password) } # length: { minimum: 6 } のテスト it { should validate_length_of(:password).is_at_least(6) } end end end各記述の解説
テストの宣言
RSpec.describe モデル名, type: :テスト形式 do
となっており、この記述でブロック内でのUserモデルのテストが実行できるRSpec.describe User, type: :model dohas_many と has_secure_password のテスト
Shoulda Matchers
を利用してモデルの関連付けと、has_secure_password
の適用を検証# has_many :books のテスト describe 'has_many' do it { should have_many(:books) } end # has_secure_password のテスト describe 'has_secure_password' do it { should have_secure_password } enddescribeとcontext でテスト記述を分ける
describe 'validation' do context 'email' do # emailのバリデーションテストを記述 end context 'password' do # passwordのバリデーションテストを記述 end endFactoryBotでテストデータを作成
ファクトリーボットで作成するテストデータを専用ファイルに定義
spec/factories/users.rbFactoryBot.define do factory :user do # データを生成する毎に通し番号をふってユニークな値を作るようにしている sequence(:email) { |n| "test#{n}@test.com" } password { 'password' } trait :upcase_email do email { 'TeSt@TEst.Com' } end end end上記ファイルを元に
let
でテストデータを作成しており、このテストデータは記述したブロック内のit .. do ~~ end
ブロックで使用できる。
コメントアウトでbinding.pry
でuser
とupcase_email_user
の中身を確認した結果を記載している。let(:user) { create(:user) } # user = <User:0x0000560469431138 id: 2610, email: "test1@test.com", password_digest: "[FILTERED]", created_at: Tue, 27 Oct 2020 14:03:04 JST +09:00, updated_at: Tue, 27 Oct 2020 14:03:04 JST +09:00> let(:upcase_email_user) { build(:user, :upcase_email) } # upcase_email_user = <User:0x00005604690c12c8 id: nil, email: "TeSt@TEst.Com", password_digest: "[FILTERED]", created_at: nil, updated_at: nil>※上記
create
とbuild
はFactoryBot
の記述を省略できる方法を適用。email バリデーション
presence:true length: { maximum: 255 } のテスト(Shoulda Matchers)
Shoulda Matchers
を用いてテストを記述# presence: true をテスト it { should validate_presence_of(:email) } # length: { maximum: 255 } をテスト it { should validate_length_of(:email).is_at_most(255) }uniqueness: { case_sensitive: false }のテスト
dupメソッド
でuser
のコピーデータを作成。
let(:user) { create(:user) }
ですでに登録済みのuser
と同じduplicate_user
が保存されないことを検証。
テストの前にemailをupcase
で大文字にすることで、大文字でも同一なemailと判定するかも合わせて検証している。
be_invalid
はバリデーションで引っかかれば(エラーが出れば)パスするit 'emailの重複保存を許容しないこと' do duplicate_user = user.dup # この時点での中身 # duplicate_user = <User:0x000055f1e1d71e90 id: nil, email: "test1@test.com", password_digest: "[FILTERED]", created_at: nil, updated_at: nil> duplicate_user.email = user.email.upcase # user.email.upcase後の中身 # #<User:0x000055f1e1d71e90 id: nil, email: "TEST1@TEST.COM", password_digest: "[FILTERED]", created_at: nil, updated_at: nil> expect(duplicate_user).to be_invalid # duplicate_user.invalid? が true になればパスする endformat: { with: /\A[\w+-.]+@[a-z\d-]+(.[a-z\d-]+)*.[a-z]+\z/i } のテスト
it '指定formatに合わないemailを許容しないこと' do # 指定formatに合致しない文字列の配列を6つ用意 invalid_emails = %w[user@foo,com user_at_foo.org example.user@foo.foo@bar_baz.com foo@bar+baz.com foo@bar..com] # userのemailにformatに合致しないemailをいれて検証 invalid_emails.each do |invalid_email| user.email = invalid_email expect(user).to be_invalid # duplicate_user.invalid? が true になればパスする end endbefore_save { email.downcase! } のテスト
upcase_email_user
のemailTeSt@TEst.Com
がsave後にはtest@test.com
になっていることを検証しており、
expect(X).to eq Y
は「XがYに等しくなること」をテストしている。it 'downcase!が正常に動作していること' do # before_saveはsaveの直前に呼び出されるためsave!する upcase_email_user.save! expect(upcase_email_user.email).to eq 'test@test.com' endpassword バリデーション
presence: true、 length: { maximum: 6 } のテスト(Shoulda Matchers)
emailと同様に
Shoulda Matchers
を用いてテストを記述context 'password' do # presence: true のテスト it { should validate_presence_of(:password) } # length: { maximum: 6 } のテスト it { should validate_length_of(:password).is_at_least(6) } end最後に
RSpec の学びはじめは構文に慣れておらず非常に苦労しました。しかし、わかりやすい解説の記事も多く、慣れてきて思った通りにテストがパスすると楽しくなってきます。
今回はモデルテストの記事を書きましたが、リクエストテストも学んだのでそちらも今後記事にできたらいいと思っています。
- 投稿日: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-27T15:22:06+09:00
【Rails】部分テンプレート
書き方
一行目が一般的
<%= render 'tweet', tweet: tweet %> <%= render partial: "tweet", locals: { tweet: tweet } %>renderメソッド
部分テンプレートを呼び出す際に利用するメソッド
partialオプション
部分テンプレート名を指定することで、該当する部分テンプレートを表示できます。
localsオプション
localsというオプションを付けることで、部分テンプレート内でその変数を使えるようになります。
collectionオプション
データの繰り返し(コレクション)を出力する際にもちいる。コレクションのメンバ(要素)ごとに部分テンプレートがレンダリングされて挿入される
<%= render partial: "prototypes/prototype", collection: @user.prototypes %>テンプレート先での記述方法は、@なしの単数型
<div class="card"> <%= link_to image_tag(prototype.image, class: :card__img ), prototype_path(prototype) if prototype.image.attached? %> <div class="card__body"> <%= link_to "#{prototype.title}", root_path, class: :card__title%> <p class="card__summary"> <%= "#{prototype.catch_copy}" %> </p> <%= link_to "by #{prototype.user.name}", root_path, class: :card__user %> </div> </div>
- 投稿日: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:34:10+09:00
【Rails】Active Storage(画像保存の設定)
使用するツール
Active Storage(gem) ※railsに最初から入っている。
MiniMagick(gem)
ImageProcessing(gem)
ImageMagick実装手順
ImageMagickをインストール
% brew install imagemagickGemをインストール
gem 'mini_magick' gem 'image_processing', '~> 1.2'Active Storageをインストール
% rails active_storage:install% rails db:migraterails active_storage:installコマンドを実行すると、Active Storageに関連したマイグレーションが作成されます。続けてマイグレートしましょう。
画像の保存
Active StorageのテーブルとMessagesテーブルのアソシエーションを定義
messages_controller.rbにて、imageカラムの保存を許可has_one_attachedメソッド
各レコードとファイルを1対1の関係で紐づけるメソッド
class モデル < ApplicationRecord has_one_attached :ファイル名 end:ファイル名には、添付するファイルがわかる名前をつけましょう。
この記述により、モデル.ファイル名で、添付されたファイルにアクセスできるようになります。また、このファイル名は、そのモデルが紐づいたフォームから送られるパラメーターのキーにもなります。画像の保存を許可するストロングパラメーター
def message_params params.require(:message).permit(:content, :image).merge(user_id: current_user.id) end保存した画像を表示
image_tagメソッド
# ファイルをモデルから指定する場合 <%= image_tag モデル名.has_one_attachedで設定したファイル名 %> <%= image_tag user.avatar %> # app/assets/ディレクトリ下の画像ファイルパスでも指定できる <%= image_tag 画像ファイルのパス %> <%= image_tag "avatar.png" %>attached?メソッド
レコードにファイルが添付されているかどうかで、trueかfalseを返すメソッドです。
ifと組み合わせて、画像の有無によって表示するかどうか判断させられます。モデル.ファイル名.attached?<%= image_tag message.image, class: 'message-image' if message.image.attached? %>variantメソッド
ファイルの表示サイズを指定できます。
モデル.ファイル名.variant(resize: '幅x高さ')記述例
html.erb<div class="card"> <%= link_to image_tag(prototype.image, class: :card__img ), prototype_path(prototype) if prototype.image.attached? %> <div class="card__body"> <%= link_to "#{prototype.title}", root_path, class: :card__title%> <p class="card__summary"> <%= "#{prototype.catch_copy}" %> </p> <%= link_to "by #{prototype.user.name}", root_path, class: :card__user %> </div> </div>画像かテキストだけのメッセージを送信
class Message < ApplicationRecord belongs_to :room belongs_to :user has_one_attached :image validates :content, presence: true, unless: :was_attached? def was_attached? self.image.attached? end end複数枚の投稿
アソシエーションの変更
has_one_attached :imageをhas_many_attached :imageへ変更
model.rbclass モデル名 < ApplicationRecord has_many_attached :images endフォームの修正
<%= form_with model: @モデル名, id: 'new_message', local: true do |f| %> <%= f.text_field :content, placeholder: 'type a message' %> <%= f.file_field :images, name: 'message[images][]', id: 'message_image' %> <%= f.submit '送信' %> <div id="image-list"></div> <% end%>ストロングパラメーターの修正
なお、配列型のパラメーターは最後に書かなければエラーを吐く。
エラーを吐く例:params.require(:モデル名).permit(images: [], :title)
controller.rbprivate def message_params params.require(:モデル名).permit(images: []) end endビューの修正
<%= image_tag @変数.image, id: 'image' if @変数.image.present? %>は削除し、以下の記述に置き換える。
html.erb<% @変数.images.each do |image| %> <%= image_tag image, class: 'images' %> <% end %>仮に1番目の画像のみを表示したい場合は、以下の記述となる。
<%= image_tag @親モデル名.image.first %>
- 投稿日: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-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-27T09:53:27+09:00
【Rails】アプリケーションを削除してみた
はじめに
テストで作成したミニアプリを削除てみました。備忘録もかねて記事に残します。
目次
1.手順
2.削除1. 手順
・データベースの削除
・フォルダ削除アプリを削除するには、ただフォルダを削除すれば良いと思っていました。
しかし、それではデータベースがの残ったままなので、不具合が起きる可能性があります。下記に参考にさせていただいた記事があります。アプリ以外もいろんなフォルダの削除方法を紹介されてるので、興味がある方は参考にしてみてください。
2. 削除
それでは削除して行きます〜
・データベースの削除
$ rails db:drop開発とテスト二つのデータベースが削除されれば成功です。
・フォルダ削除
$ cd .. $ rm [アプリ名]コマンドで削除可能ですが、ファインダーからゴミ箱に入れても削除できます。
以上です!
最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜参考
- 投稿日:2020-10-27T09:11:52+09:00
個人的に便利なアプリや開発ツールをまとめてみた(開発ツール編)
今回は、「開発ツール編」として筆者がRailsで開発環境を構築するときに導入する開発ツールをまとめてみました。
いつかまたセットアップする機会がきたときに役に立てばいいと思っております!neovimを使ってRails開発が行えるところまでをゴールとします。
前回のアプリ編もどうぞ
導入するもの
名前 用途 Homebrew パッケージマネージャ Alfred 万能ランチャーアプリ 白源 フォント iTerm2 高機能ターミナル zsh シェル prezto zsh用コンフィグフレームワーク neovim エディタ iceberg テーマ Git バージョン管理 rbenv Rubyのバージョン管理 Docker 仮想プラットフォーム Homebrew
MacOSXシステム上でソフトウェアの導入を単純化してくれるパッケージマネージャ。
これで導入したソフトウェア群を、brewfileを用いて他環境へ簡単に移行することが可能です。
必要なものを一カ所に集めてくれるので、管理の手間が省けて便利ですね。
これから記載するものはほとんどこのツールを用いて導入していくので、最初にインストールしておくのが吉。インストール手順
公式サイトの通り、ターミナル上で下記コマンドを実行するだけです。
Command + SpaceでSpotlight検索を起動して、「Terminal」と入力するとターミナルが起動します。$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"途中、パスワードを求められますのでMacにログインしているユーザのパスワードを入力してください。
$ Password:
また、Homebrewは「Command line tools for Xcode」というソフトウェアに依存しており、途中でこのソフトウェアのインストールを求められますので、インストールしてください。
※画像は参考ですが、同じようにソフトウェアアップデートが立ち上がりインストールを求められます。
以下のように出力されたら完了。
一応doctorコマンドで正常にインストールできたか確認します。==> Next steps: - Run `brew help` to get started - Further documentation: https://docs.brew.sh $ brew doctor Your system is ready to brew.Alfred
Alfredはアプリ編に記載したかったのですが、Homebrewを使ってどのような環境であっても必ず持って行きたいアプリなのでこちらに記載しました。
Mac標準のSpotlightと同じようにアプリランチャーとしても働きますし、システムの機能をショートカットから呼出してファイルを一括で編集したり、スニペット登録機能があったり色々な機能があります。
課金すると上記のスニペット登録機能・ファイル操作機能が使えますが、そもそもSpotlightより便利で高機能なので導入しておいて損はないと思います。
筆者は全然使いこなせていないですが、かなり生産性が上がるみたいで少し余裕ができたら学んでいきたいと思っております。インストール手順
Homebrewを使ってインストールします。
Homebrewは基本的にCUIをインストールするものなのですが、homebrew-caskという拡張機能を使用することによりGUIをインストールすることが可能となります。この拡張機能をまず有効にしましょう。
下記のコマンドを実行すると、Homebrewにcaskが追加されます。$ brew cask
本来はcaskのあとにインストールしたいアプリの名前を入れる必要があり、「Error: Invalid usage: No subcommand given.」と出力されますが、コマンドの実行方法がおかしいってだけでcaskは追加されるので気にしないでください。
その後、Alfredをcaskを介してインストールします。
もちろん上記のcaskのインストールを飛ばしてこちらを実行してもらっても構わないです。$ brew cask install Alfred alfred was successfully installed!Spotlightと同じCommand + Spaceで起動したい場合は、インストール出来たらMacのシステム環境設定→キーボード→ショートカットを開きSpotlightのショートカットを無効化してください。
その後、Alfredを起動してショートカットを変更して導入は完了です。
白源
エディタ上で見やすいフォントを色々試したのですが、個人的に一番見やすくてCUI上でアイコンをフォントとして出力するNerd Fontsに対応しているのでおすすめ。
プログラミング用のフォントとして有名なRictyをカスタマイズしているので完成度が高く、今でも定期的に更新され視認性がどんどん上がっていっており、非常に活発なフォントなのであります。
詳しくは作者様の記事をご覧ください。インストール手順
cask同様にフォント用のHomebrewの拡張機能をインストールして、そちらを介して白源フォントをインストールします。$ brew tap homebrew/cask-fonts $ brew cask install font-hackgen-nerd以降の項目でこちらのフォントは使用しますので、ここでは導入のみにとどめます。
もしお気に入りのフォントがあるなら、cask-fontsをインストール後に下記コマンドでHomebrewで扱われているか調べて、そちらを利用しても構いません。$ brew search フォント名
iTerm2
Mac標準のターミナルを高機能にしたもの。
後述するエディタ用テーマ「iceberg」が、ターミナルではフルカラー出力に対応しておらず色味が思い通りに表示されなかったので導入した。
以下の記事を見てtmuxを入れなくてもコピーモードで色々できるんだなと思ったのも大きい。インストール手順
下記を実行してインストール。$ brew cask install iTerm2導入はこれでいいですが、例えばダウンロードとかのディレクトリにアクセスしたときにiTermにアクセス許可を与えるかどうかの通知が表示されます。
この通知がいろんなディレクトリにアクセスしたときに表示されるので気になる人は、システム環境設定→セキュリティとプライバシーのフルディスクアクセスにiTerm.appを追加してください。
後述するicebergの項で配色に関しては設定しますので、ここではステータスバーとフォントの設定を行います。
まずPreferences→Profileにある+マークで新しいプロファイルを作成しましょう。名前は適当でいいです。筆者は「iceberg」としました。
次にTextタブを開き下にあるFontを、先ほど入れた「白源」にします。
また、ステータスバーの表示位置がデフォルトでは上なので、Preferences→AppearanceのStatus bar locationで下などに変更できる。
Sessionタブに移り、一番下のStatus bar enabledにチェックをつけます。
あとはConfigure Status Barボタンを押して表示させたいアイテムをActive Componentsにドラッグして、Advancedで色とフォントの設定を行います。
筆者の場合は、背景色とアイテムの区切り線の色はicebergの背景色と同じ#161821にして、フォントも白源としました。
(iMacの場合、バッテリー表示は不要ですがMacbookとかと設定を同期したい場合はつけてもいいかもしれません。)
設定できたらOKを押して閉じます。
作ったプロファイルは、左下のOther Actionsを押してデフォルトに設定してください。
その後再起動すると反映されます。
また、このプロファイルはOther Actionsで、JSONとしてエクスポートできますので、他のPCでインポートすれば設定を同期できるので覚えておくと便利です。
zsh
Catalinaを使っていたら導入する必要はありませんが、Homebrewで最新バージョンをインストールしてそちらを利用します。
インストール手順
Catalinaの場合、ログインシェルがzshなのでそのコマンドの位置と、バージョンを見ておきます。$ which zsh /bin/zsh $ /bin/zsh --version zsh 5.7.1次に、Homebrewを介してzshをインストールしてそれをログインシェルとするために、/etc/shellsをvimで編集します。
パスワードを求められるのでログインユーザーのパスワードを入力してください。$ brew install zsh $ sudo vim /etc/shells Password:開いたらファイルの一番下に「/usr/local/bin/zsh」を追記して、下記コマンドでシェルを変更します。
$ chsh -s /usr/local/bin/zsh実行できたらターミナルを再起動。
起動したらもう一度、zshの位置とバージョンを確認して、変更が確認できたら完了です。$ which zsh /usr/local/bin/zsh $ zsh --version zsh 5.8prezto
zshrcファイルをあれこれいじるのが面倒な場合、preztoを入れればある程度便利に設定を行ってくれます。
またプロンプトも少しおしゃれにできます。インストール手順
ターミナルを起動して下記を実行していきます。# 先に変数を定義してpreztoの配置場所及び、設定ファイルの保存場所を決めておく $ ZDOTDIR="~/.config/zsh" # prezto本体をクローンする $ git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto" # 設定ファイルを生成する $ setopt EXTENDED_GLOB for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}" done # シェルをデフォルトにする $ chsh -s /usr/local/bin/zsh # ZDOTDIRの箇所に生成された.zshenvをルートディレクトリに移動し、編集します。 $ mv ~/.config/zsh/.zshenv ~/.zshenv $ vim .zshenv.zshenv# 省略 # 設定ファイル保存先 export ZDOTDIR="$HOME/.config/zsh"次にpreztoに便利なモジュールを追加します。
$ vim ~/.config/zsh/.zpreztorc
32行目あたりの箇所を編集します。
.zpreztorczstyle ':prezto:load' pmodule ¥ 'environment' \ 'terminal' \ 'editor' \ 'history' \ 'directory' \ 'spectrum' \ 'utility' \ 'completion' \ 'syntax-highlighting' \ # これを追加 'autosuggestions' \ # これも追加 'prompt'シェルを再起動すれば完了。
neovim
vimを拡張した派生エディタ。
JetbrainsなどのIDE、VSCODEとこれが現時点で最良の選択なのかなーっと思ってます。
正直、あれこれカスタマイズしてメンテナンスしていかないといけないので、それらが一番楽なのはIDEです。
ただVimの操作ってすごい楽なんですよね。で、IDEもVSCODEもそれらのメリットを享受できるけど、完璧じゃないんです。
ここはもう好みの問題だとは思いますが。インストール手順
下記コマンドを実行。$ brew install nvimインストール自体は完了しており、続けて設定ファイルを作成する。
$ mkdir ~/.config/nvim $ touch ~/.config/nvim/dein.toml $ touch ~/.config/nvim/dein_lazy.toml $ touch ~/.config/nvim/init.vim $ vi ~/.config/nvim/init.vim作成したら設定を色々編集していくのだが、dein.vimを導入し、最低限のものをまとめたのが以下になる。
dein.vimはプラグインマネージャで、vimに拡張機能をもたらすモジュールを一括管理してくれる。
以下のように書き換えて、再度neovimを起動したら自動的にインストールしてくれる。
エラーなどは気にしなくてよい。init.vim" dein.vim settings let s:dein_dir = expand('~/.cache/dein') let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim' " dein installation check if &runtimepath !~# '/dein.vim' if !isdirectory(s:dein_repo_dir) execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir endif execute 'set runtimepath^=' . s:dein_repo_dir endif " begin settings if dein#load_state(s:dein_dir) call dein#begin(s:dein_dir) " .toml file let s:rc_dir = expand('~/.config/nvim') if !isdirectory(s:rc_dir) call mkdir(s:rc_dir, 'p') endif let s:toml = s:rc_dir . '/dein.toml' let s:lazytoml = s:rc_dir . '/dein_lazy.toml' " read toml and cache call dein#load_toml(s:toml, {'lazy': 0}) call dein#load_toml(s:lazytoml, {'lazy': 1}) " end settings call dein#end() call dein#save_state() endif " plugin installation check if dein#check_install() call dein#install() endif " plugin remove check let s:removed_plugins = dein#check_clean() if len(s:removed_plugins) > 0 call map(s:removed_plugins, "delete(v:val, 'rf')") call dein#recache_runtimepath() endif filetype plugin indent on syntax enable " リーダーキーの変更 let mapleader = "\<Space>" colorscheme iceberg set termguicolors set encoding=utf-8 set nrformats= set tabstop=2 set softtabstop=2 set shiftwidth=2 set expandtab set autoindent set smartindent set nobackup set noswapfile set clipboard& set clipboard^=unnamed set number set norelativenumber set title set nocursorline set list set listchars=tab:\|\ ,trail:-,eol:↲,extends:»,precedes:«,nbsp:% set showmatch set matchtime=1 set hlsearch set whichwrap=b,s,<,>,[,] set tags=./tags; set completeopt=menuone,noinsert set viminfo+=n~/.config/nvim/.viminfo " j,kキーで表示行移動 nnoremap <silent> k gk nnoremap <silent> gk k nnoremap <silent> j gj nnoremap <silent> gj j " 折り返し移動 set whichwrap=b,s,<,>,[,] " 補完のEnterでは挿入しない inoremap <expr><CR> pumvisible() ? "<C-e>" : "<CR>"iceberg
色々テーマはあるが、寒色で目に優しい配色が気に入っている。
公式サイトを見て気に入ったら使ってみてほしい。インストール手順
iTerm2とneovimそれぞれに導入していく。
まずはneovim。dein.tomlを開いて、icebergを追加。
ほかにdein.vim自体と、vimのステータスバーを格好良くするairlineを追加。vi ~/.config/nvim/dein.tomldein.toml[[plugins]] repo = 'Shougo/dein.vim' [[plugins]] repo = 'cocopon/iceberg.vim' [[plugins]] repo = 'vim-airline/vim-airline'その後、neovimを起動したら自動的にインストールされる。
次にiTerm2の設定をしていく。
vimでiTermのカラー設定用ファイルを作成して、以下の記述通りに保存する。$ vi iceberg.itermcolors
iceberg.itermcolors<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Ansi 0 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.12941177189350128</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.094117648899555206</real> <key>Red Component</key> <real>0.086274512112140656</real> </dict> <key>Ansi 1 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.47058823704719543</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.47058823704719543</real> <key>Red Component</key> <real>0.88627451658248901</real> </dict> <key>Ansi 10 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.55686277151107788</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.7921568751335144</real> <key>Red Component</key> <real>0.75294119119644165</real> </dict> <key>Ansi 11 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.5372549295425415</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.69411766529083252</real> <key>Red Component</key> <real>0.91372549533843994</real> </dict> <key>Ansi 12 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.81960785388946533</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.67450982332229614</real> <key>Red Component</key> <real>0.56862747669219971</real> </dict> <key>Ansi 13 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.82745099067687988</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.62745100259780884</real> <key>Red Component</key> <real>0.67843139171600342</real> </dict> <key>Ansi 14 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.80784314870834351</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.76862746477127075</real> <key>Red Component</key> <real>0.58431375026702881</real> </dict> <key>Ansi 15 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.87058824300765991</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.83137255907058716</real> <key>Red Component</key> <real>0.82352942228317261</real> </dict> <key>Ansi 2 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.50980395078659058</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.7450980544090271</real> <key>Red Component</key> <real>0.70588237047195435</real> </dict> <key>Ansi 3 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.47058823704719543</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.64313727617263794</real> <key>Red Component</key> <real>0.88627451658248901</real> </dict> <key>Ansi 4 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.7764706015586853</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.62745100259780884</real> <key>Red Component</key> <real>0.51764708757400513</real> </dict> <key>Ansi 5 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.78039216995239258</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.57647061347961426</real> <key>Red Component</key> <real>0.62745100259780884</real> </dict> <key>Ansi 6 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.7607843279838562</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.72156864404678345</real> <key>Red Component</key> <real>0.5372549295425415</real> </dict> <key>Ansi 7 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.81960785388946533</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.78431373834609985</real> <key>Red Component</key> <real>0.7764706015586853</real> </dict> <key>Ansi 8 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.5372549295425415</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.43921568989753723</real> <key>Red Component</key> <real>0.41960784792900085</real> </dict> <key>Ansi 9 Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.5372549295425415</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.5372549295425415</real> <key>Red Component</key> <real>0.91372549533843994</real> </dict> <key>Background Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.12941177189350128</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.094117648899555206</real> <key>Red Component</key> <real>0.086274512112140656</real> </dict> <key>Badge Color</key> <dict> <key>Alpha Component</key> <real>0.5</real> <key>Blue Component</key> <real>0.0</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.1491314172744751</real> <key>Red Component</key> <real>1</real> </dict> <key>Bold Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.87843137979507446</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.70980393886566162</real> <key>Red Component</key> <real>0.54901963472366333</real> </dict> <key>Cursor Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.81960785388946533</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.78431373834609985</real> <key>Red Component</key> <real>0.7764706015586853</real> </dict> <key>Cursor Guide Color</key> <dict> <key>Alpha Component</key> <real>0.25</real> <key>Blue Component</key> <real>1</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.9268307089805603</real> <key>Red Component</key> <real>0.70213186740875244</real> </dict> <key>Cursor Text Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>1</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>1</real> <key>Red Component</key> <real>0.99607843160629272</real> </dict> <key>Foreground Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.81960785388946533</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.78431373834609985</real> <key>Red Component</key> <real>0.7764706015586853</real> </dict> <key>Link Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.73423302173614502</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.35916060209274292</real> <key>Red Component</key> <real>0.0</real> </dict> <key>Selected Text Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.81960785388946533</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.78431373834609985</real> <key>Red Component</key> <real>0.7764706015586853</real> </dict> <key>Selection Color</key> <dict> <key>Alpha Component</key> <real>1</real> <key>Blue Component</key> <real>0.25882354378700256</real> <key>Color Space</key> <string>sRGB</string> <key>Green Component</key> <real>0.17254902422428131</real> <key>Red Component</key> <real>0.15294118225574493</real> </dict> </dict> </plist>このファイルをiTermのPreferences→Profile→Color Presetsでインポートを行うと適用される。
Git
ソースコードなどの変更履歴を追跡できるバージョン管理システム。
インストール手順
Homebrew経由でインストールします。
まず元から入っているgitのバージョンを調べて、Homebrewでインストールします。$ git --version git version 2.24.3(Apple git-128) $ brew install gitこのままでは元からMacに入っているgitが使われてしまうので、パスを通します。
$ vim ~/.config/zsh/.zshrc
.zshrcexport PATH="/usr/local/bin/git:$PATH"一度ターミナルを再起動して、gitのバージョンが変わっていれば成功です。
$ git --version git version 2.29.1rbenv
Rubyのバージョンを切り替えたり、管理することが簡単にできます。
とりあえず入れておいて損はない。インストール手順
Homebrewでインストール。$ brew install rbenv $ rbenv -v 1.1.2次にパスを通します。
またRBENV_ROOT変数にrbenvのshimsとversionsがあるディレクトリの位置を指定します。
最後のrbenv initは必須です。$ vim ~/.config/zsh/.zshrc
.zshrcexport RBENV_ROOT="~/.local/share/rbenv" export PATH="$RBENV_ROOT/bin:$PATH" eval "$(rbenv init -)"次にこのrbenvを通してRubyをインストールします。
# 下記コマンドでインストール可能なRubyのバージョンが一覧で見られます $ rbenv install -l # バージョンを決めたらインストールします $ rbenv install 2.7.2 # インストールしたバージョンを実行可能にします $ rbenv global 2.7.2 # 下記コマンドを実行して、指定したバージョンにアスタリスクがついていたらおk $ rbenv versions system * 2.7.2Docker
仮想環境で開発を行うプラットフォームを提供するツール。
インストール手順
以下からDocker for Macをダウンロードしてインストールする。
公式サイトまとめ
Dockerを使って実際に仮想環境を作成する方法は、以下の記事を参考にしてください。
Vimの他のプラグインや、細かい設定は省いていますがここは個人の好みが含まれるため、色々設定してみるといいかもしれません。
筆者もまだ試している状態なので、揃ってきたら記事にしたいと思います。最後までお読みいただきありがとうございました!
- 投稿日: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: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/現場からは以上です!