- 投稿日:2019-04-17T23:24:14+09:00
ハッシュ関数とは
ハッシュ関数とは
プログラミング初心者なりに『ハッシュ関数とは』何かをまとめてみた。
ハッシュ関数とは
一言でいうと『入力されたデータに対して適当な値を返してくれる関数。』
そしてその返ってきた値をハッシュと呼ぶ。
ちなみに関数にいれるものは『引数』呼ぶ。
ハッシュは引数として関数にいれた値をぐちゃぐちゃにしてハッシュとして返してくれる特性があるため、第三者にばれてはいけないパスワードなどの設定になどに使われる。
ちょっと汚い話になるけれど、
ラーメン(引数)を食べたら
それが体(関数)に入って
うんち(ハッシュ)としてでてくる。うんちを見た人は一体何を食べたのか分からない。
つまりハッシュは、入力されたデータに対して適当な値を返してくれる関数。だと思えばOKだと思う。
- 投稿日:2019-04-17T22:51:21+09:00
RailsプロジェクトのGitHubリポジトリ主要言語判定がHTMLになってしまうのをRubyにする
- 投稿日:2019-04-17T22:32:52+09:00
Railsでテーブルのカラムを確認したい時
Railsにてカラムを確認したい時は、コンソールからモデル名を入力すれば確認できる様子
2.4.1 :017 > User => User(id: integer, organization_id: integer, login_id: string, password_digest: string, first_logged_in_at: datetime, last_logged_in_at: datetime, created_at: datetime, updated_at: datetime, deleted_at: datetime)補足:Hoge (call 'Hoge.connection' to establish a connection)が出た時
=> Hoge (call 'Hoge.connection' to establish a connection)上記のように表示されたときは
ActiveRecord::Base.clear_cache!
をコンソールに入力すれば良いらしい。
- 投稿日:2019-04-17T22:23:03+09:00
アソシエーションって? 初心者メモ
アソシエーションとは
モデル(テーブル)間の紐付けをする機能のこと。
アソシエーションを使うとデータの呼び出しが楽になる!
どんなときに使うの?
例)userが複数の画像を追加するとき
id user image1 image2 image3 1 A photo1 photo4 photo7 2 B photo2 photo5 photo8 3 C photo3 photo6 photo9 ↑これはダメなテーブルの作り方
画像を追加するたびにカラムを増やさなきゃいけない
いちいちコンソルで$rails g modelするのなんてめんどくさすぎテーブルを分けるしかない
![]()
userテーブル
id user 1 A 2 B 3 C imageテーブル
id image article_id 1 photo1 1 2 photo2 2 3 photo3 3 4 photo4 1 5 photo5 2 6 photo6 3 7 photo7 1 バラバラになっちゃったのでuserテーブルとimageテーブルは
関係のあるテーブルだとわからせたい→
アソシエーションを使おう
アソシエーションを定義する
アソシエーションを使う条件
①モデルクラスにhas_manyやbelong_toなどの定義がされている。
②所属する側のテーブルに「所属するカラム名_id」というカラムがある。例)ツイートとユーザーを関連づける
全てのツイートはいずれかのユーザーが作成したもので、
ユーザーは自分の作成したツイートを複数もっているということになる。
userから見るとtweetを複数持っている→has_manyの関係
app/models/user.rbclass User < ApplicationRecord has_many :tweets end
tweetから見るといずれかのuserに属している→beong_toの関係
app/models/tweet.rbclass Tweet < ApplicationRecord belongs_to :user endアソシエーションを実装する
アソシエーションを使用しない場合
ターミナルでrails cコマンド実行 [1] pry(main)> user = User.find(1) [2] pry(main)> Tweet.where(user_id: user.id)
tweetsテーブルに対してuser_idがuserのidと等しいコードを取得している。
アソシエーションを使用した場合
ターミナルでrails cコマンド実行 [1] pry(main)> user = User.find(1) [2] pry(main)> user.tweets
Userモデルに「user has many tweets」の記述をしたので
userモデルのインスタンス.tweetsでそのインスタンスが持つツイートを取得できる。
→短くて楽!
- 投稿日:2019-04-17T22:05:08+09:00
【Rails】ローカル開発環境で他の端末からrails serverに接続する方法
IPアドレス確認
ターミナルで
ifconfig
コマンドを入力して、wi-fiで接続しているインターフェイスのIPアドレスを確認する。$ ifconfig lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201<PERFORMNUD,DAD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 XHC0: flags=0<> mtu 0 XHC20: flags=0<> mtu 0 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether xxxxxxxxxxxxxxxxxxx inet6 fe80::a5:5017:3c48:df62%en0 prefixlen 64 secured scopeid 0x6 inet 192.168.11.10 netmask 0xffffff00 broadcast 192.168.11.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active↑
en0:
を見ると192.168.11.10
であるのが分かる。serverを立ち上げる。
serverのPCはrails serverを立ち上げます。この時
-b
オプションが必要。rails s -b 0.0.0.0外部端末から接続
rails s
したPCと同じWi-Fi(正確には同一のSSID)に接続し、
ブラウザのアドレスバーにserverのIPアドレスと3000番ポート番号を指定して入力する。
今回の場合、サーバーのPCのIPアドレスが192.168.11.10なので、192.168.11.:3000
と入力する。これでherokuなどにデプロイしなくても、スマホから画面確認などが出来ます。
また、httpなのでwiresharkなどでパケットキャプチャーすれば中身が見れます。
- 投稿日:2019-04-17T22:05:08+09:00
【Rails】development環境で外部端末からserverに接続する方法
IPアドレス確認
ターミナルで
ifconfig
コマンドを入力して、wi-fiで接続しているインターフェイスのIPアドレスを確認する。$ ifconfig lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201<PERFORMNUD,DAD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 XHC0: flags=0<> mtu 0 XHC20: flags=0<> mtu 0 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether xxxxxxxxxxxxxxxxxxx inet6 fe80::a5:5017:3c48:df62%en0 prefixlen 64 secured scopeid 0x6 inet 192.168.11.10 netmask 0xffffff00 broadcast 192.168.11.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active↑
en0:
を見ると192.168.11.10
であるのが分かる。serverを立ち上げる。
serverのPCはrails serverを立ち上げます。この時
-b
オプションが必要。rails s -b 0.0.0.0外部端末から接続
rails s
したPCと同じWi-Fi(正確には同一のSSID)に接続し、
ブラウザのアドレスバーにserverのIPアドレスと3000番ポート番号を指定して入力する。
今回の場合、サーバーのPCのIPアドレスが192.168.11.10なので、192.168.11.:3000
と入力する。これでherokuなどにデプロイしなくても、スマホから画面確認などが出来ます。
また、httpなのでwiresharkなどでパケットキャプチャーすれば中身が見れます。
- 投稿日:2019-04-17T21:31:30+09:00
Railsの部分テンプレ(partial)をラッピングして、collection変数を渡す
TL;DR
_item.html.slimh3 Item Name: #{item.name} p Item Index: #{item_counter}_wrapped_item.html.slimh2 Item Wrapper .item-area = render partial: 'item',\ locals: { item: wrapped_item, item_counter: wrapped_item_counter }index.html.slimh1 Naked Items .naked-items = render partial: 'item', collection: @items h1 Wrapped Items .wrapped-items = render partial: 'wrapped_item', collection: @itemsはじめに
パーシャルをrenderする際、
<%= render partial: 'item', collection: @items %>
を使うと、.each
文より見通しが良くなるだけでなく、性能も向上されるとされています。
しかし、パーシャルにそれぞれラッピングやデコレーションをしたい場合、どうすれば良いのでしょう。発見
_item.html.slimh3 Item Name: #{item.name} p Item Index: #{item_counter}_wrapped_item.html.slimh2 Item Wrapper .item-area = render partial: 'item'index.html.slimh1 Naked Items .naked-items = render partial: 'item', collection: @items h1 Wrapped Items .wrapped-items = render partial: 'wrapped_item', collection: @items上記の構文のように、そのまま
_item.html.slim
にラッピングを当てて、renderingしようとする時、Template::Error
が発生し、変数item
がないと言われました。ActionView::Template::Error (undefined local variable or method `item' for #<#<Class:0x00007f8d8fa105d0>:0x00007f8da6f657a8>: 1: h3 Item Name: #{item.name} 2: p Item Index: #{item_counter}だったら変数
item
を手動で渡せば良いのでは?と思って、変数wrapped_item
をitem
として渡しました。もちろん、Indexも必要な時は、#{variable_name}_count
も伝播しなければいけません。_wrapped_item.html.slimh2 Item Wrapper .item-area = render partial: 'item',\ locals: { item: wrapped_item, item_counter: wrapped_item_counter }参考
- 投稿日:2019-04-17T21:29:50+09:00
【大反省】素人がAWSS3をいじっていると「Your AWS Account is compromised!」とメールが来た
Railsでポートフォリオを作成しておりまして、Herokuへのデプロイ後の画像保存先をAWSS3に指定しました。
すると後日AWS様からメールで「Your AWS Account is compromised!」とご連絡頂き、結果的にバケットとIAMを削除して作り直したのですが、そもそもなぜそんなことになったのかを反省しつつ書いておきます。
原因:AccessKeyをベタ書きしてcommitしてしまっていた
AWSS3を使う場合Active Storageを使って、保存先を
config/storage.yml
で以下のように書くかと思います。storage.ymlamazon: service: S3 access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> region: ap-northeast-1 #東京 bucket: #bucketnameただ僕は以前の記事でも書いた通り、
#string does not have #dig method
というエラー解決に苦しみ、結果的にaccess_key_id
とsecret_access_key
をベタ書きしてした状態でgit commit
して全世界に僕のアクセスキーを大公開してしまっていたわけです。まあ、僕のリポジトリのコードなど詳しく見る人はいないだろうという甘い想定でしたが、実際はBotによって攻撃される危険性などがあるそうで、その辺りの想定が甘すぎました、、、
とりあえずポートフォリオとして完成させることを急ぐあまり、セキュリティの意識が大幅に欠落していて、まだ個人でポートフォリオを実装している段階なのでマシですが、これが実際の業務だったら死んでいたな、、、と猛省しました
対処法
- AWS ルートアカウントのユーザーパスワードを変更する。
- すべてのルートおよび AWS Identity and Access Management (IAM) アクセスキーを削除するか、交換する。
- 危険にさらされている IAM ユーザーを削除し、他のすべての IAM ユーザーのパスワードを変更する。
- EC2 インスタンスおよび AMI、EBS ボリュームおよびスナップショット、および IAM ユーザーなどの作成していないアカウントのリソースを削除する。
- AWS サポートから受け取った通知には、AWS サポートセンター経由で返信してください。
参照元:自分の AWS アカウントが危険にさらされているようです
上記を実行した上で、再度バケット、IAMを作り直して実装し直しました。
以上、大反省の記録でした。
- 投稿日:2019-04-17T20:53:52+09:00
Rails6 のちょい足しな新機能を試す4 (Date#before? Date#after? 編)
はじめに
Rails 6 に追加されそうな新機能を試す第3段。
Date#before?
Date#after?
編です。
記載時点では、Rails は 6.0.0.beta3 です。gem install rails --prerelease
でインストールできます。試してみる
今回は、rails の projectを作らなくても試せるので、直接、ruby (irb) から試してみましょう。
$ irb -ractive_support/core_ext # 今日は昨日より後? irb(main):001:0> Date.today.after?(Date.today.yesterday) => true # 今日は明日より後? irb(main):002:0> Date.today.after?(Date.today.tomorrow) => false # 今日は昨日より前? irb(main):003:0> Date.today.before?(Date.today.yesterday) => false # 今日は明日より前? irb(main):004:0> Date.today.before?(Date.today.tomorrow) => true # 今日は今日より後? irb(main):005:0> Date.today.after?(Date.today) => false # 今日は今日より前? irb(main):006:0> Date.today.before?(Date.today) => false
DateTime
,Time
,TimeWithZone
にも同様にbefore?
とafter?
が追加されています。これ、わかりやすいんですかね。英語ペラペラの人にとっては自然なのかもですが、そうでない人には、ちょっと微妙かもと思ったり思わなかったり。以下みたいな読み違いをしそうな気がしないでもない...
# 今日の後は昨日? => この解釈が間違い。 irb(main):001:0> Date.today.after?(Date.today.yesterday) => trueこのメソッドは、
:>
がafter?
の<:
がbefore?
の aliasとして定義されています。と書こうとしたのですが、どうやらそうではなかったようです。irb(main):015:0> Date.today.method(:before?).original_name => :before? irb(main):016:0> Date.today.method(:after?).original_name => :after?アレッと思ってソースを調べてみました。
irb(main):018:0> Date.today.method(:before?).source_location => ["/usr/local/bundle/gems/activesupport-6.0.0.beta3/lib/active_support/core_ext/date_and_time/calculations.rb", 64] irb(main):019:0> Date.today.method(:after?).source_location => ["/usr/local/bundle/gems/activesupport-6.0.0.beta3/lib/active_support/core_ext/date_and_time/calculations.rb", 69]実際のコードはこんな感じです。
calclulation.rb# Returns true if the date/time falls before <tt>date_or_time</tt>. def before?(date_or_time) self < date_or_time end # Returns true if the date/time falls after <tt>date_or_time</tt>. def after?(date_or_time) self > date_or_time end調べてみたら、alias で定義していたものを refactoring してました。
元のPRが Add
before?
andafter?
methods to date and time classes で、
refactoring の PR が Move implementation ofbefore?
andafter?
toDateAndTime::Calculations
です。参考情報
- 投稿日:2019-04-17T20:23:12+09:00
【Rails】 jQueryが動作しない時の対処法 (読み込む順番)
いつも忘れてしまうので備忘録。
ダメなパターン
_head.html.erb<%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %> <!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
javascript_include_tag
→jQuery CDN
の順番では期待通りになりませんでした。正のパターン
_head.html.erb<!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %>
jQuery CDN
→javascript_include_tag
の順番だと期待値通りの動作!まとめ
先にjQueryロードしないとスクリプト読めないって話。(Railsに限った話じゃない・・・)
- 投稿日:2019-04-17T20:23:12+09:00
【Rails】 jQueryが動作しない時の対処法 (読み込む順番に気をつけて)
いつも忘れてしまうので備忘録。
ダメなパターン
_head.html.erb<%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %> <!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
javascript_include_tag
→jQuery CDN
の順番では期待通りになりませんでした。正のパターン
_head.html.erb<!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %>
jQuery CDN
→javascript_include_tag
の順番だと期待値通りの動作!まとめ
先にjQueryロードしないとスクリプト読めないって話。(Railsに限った話じゃない・・・)
- 投稿日:2019-04-17T20:23:12+09:00
【Rails】 jQuery/jsファイル 読み込む順番
いつも忘れてしまうので備忘録。
ダメなパターン
_head.html.erb<%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %> <!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
javascript_include_tag
→jQuery CDN
の順番では期待通りになりませんでした。正のパターン
_head.html.erb<!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <%= stylesheet_link_tag 'style', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'selectordie' %>
jQuery CDN
→javascript_include_tag
の順番だと期待値通りの動作!まとめ
先にjQueryロードしないとスクリプト読めないって話。(Railsに限った話じゃない・・・)
- 投稿日:2019-04-17T18:33:00+09:00
本番API server に graphql を段階導入
@_nishisuke です!
フリーランスやってます!
ある案件で本番iosのAPI serverとして既に動いてる rails にgraphqlを導入しました。
(この案件では実装の全権限をもらってます。)
いきなりclient側の実装を変えるのは変更が大きすぎると判断しました。
第一段階としてサーバーのシリアライザーレイヤーだけをgraphqlに置き換えようとしました。
api serverはrequest specが書いてあり、json-schemaによりresponse jsonが担保されています。
https://github.com/ruby-json-schema/json-schema
一部の読み込みqueryだけをターゲットにし書き込み処理は最初のスコープに入れませんでした。
rails で graphql
https://qiita.com/nishisuke/items/c4f6065b069b2c1f3083
install
gem 'graphql'before
app/controllers/users_controller.rbclass UsersController < ApplicationController def index user = User.where(適当なコンディション).includes(適当なアソシエーション) render json: UserSerializer(user) end endafter
app/controllers/users_controller.rbclass UsersController < ApplicationController USER_SCHEMA = <<~USER_SCHEMA { users { name } } USER_SCHEMA def index gql_res = MyApplicationSchema.execute(USER_SCHEMA).to_h raise SomeError unless gql_res['errors'].nil? render json: gql_res.to_json end end結果
serializer layerだけ変えたかったが、controllerも変更を余儀なくされました。
MVC -> M + graphql
のイメージです。gemの注意点
- graphql-rubyのqueryはdefaultでcamelcase
- graphql-rubyは200 statusでerror jsonを返そうとする
所感
思ったより簡単にできた。
実態と実装の構造が近くなって、変更を加えるのが容易になった。
- 投稿日:2019-04-17T17:41:26+09:00
Stripe ConnectのCustomアカウントで、子アカウントへの入金情報などを取得する方法(アカウントヘッダー)
Stripe Connectでの子アカウントに関する情報をAPIで取得したい
ドキュメントが少しわかりづらかったので記事を書きました。
プラットフォーム上で子アカウントの情報(例:決済情報、入金情報)を取得し、マイページなどで表示する方法です。
Stripe APIにはアカウントヘッダーという機能があり、APIを呼び出す上で、どのAccountに紐づいた情報を取得するのかを指定できます。このアカウントヘッダーを使用しない場合は、デフォルトで親アカウントが指定されるようです。# 例) 子アカウント(ID: acct_xxxxxxxxxx)に対して行われた最新の入金を3件取得する Stripe::Payout.list( {limit: 3}, {stripe_account: "acct_xxxxxxxxxx"} )このように、第一引数にパラメータ、第二引数にacct_idを指定することで、特定のアカウントに基づいた情報を取得できるようになります。
例) ある月の売上の入金額を取得する
私が開発しているCtoCサービスでは、子アカウントの売上の入金スケジュールを月末締め、翌月末払いにしています。そこで欲しい情報は、毎月の入金情報です。
例えば2019年3月に作成された入金情報を取得したい場合は、以下のようにします。beginning_of_month = Date.new(2019, 3).to_time.to_i end_of_month = Date.new(2019, 3).end_of_month.to_time.to_i payout = Stripe::Payout.list( {created: {gte: beginning_of_month, lte: end_of_month}}, #gteが以上、lteが以下。日時の範囲指定が独特w {stripe_account: "acct_xxxxxxxxxx"} ) # 入金額 payout.data[0].amount # 入金予定日 Time.at(payout.data[0].arrival_date).strftime("%Y/%m/%d")間違いなどあればご指摘頂けると嬉しいです。
- 投稿日:2019-04-17T17:23:21+09:00
メルカリでハマったところ3
capistranoでデプロイ時にエラー
unicornが起動できないみたい 00:17 unicorn:start 01 $HOME/.rbenv/bin/rbenv exec bundle exec unicorn -c /var/www/freemarket_47nagoya/current/config/unicorn.rb -E production -D 01 master failed to start, check stderr log for details ログを確認しても何も書かれていなかった Caused by: SSHKit::Command::Failed: bundle exit status: 1 bundle stdout: Nothing written bundle stderr: master failed to start, check stderr log for details ec2のcurrentディレクトリで実行してもダメ current]$ unicorn_rails -c config/unicorn.rb -E production /home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/unicorn-5.4.1/lib/unicorn/configurator.rb:592:in `working_directory': config_file=config/unicorn.rb would not be accessible in working_directory=/var/www/freemarket_47nagoya/releases/current (ArgumentError)psコマンドって何よ
詳しい情報を見たい時は -efオプションをつけるみたい
参考:https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_71/com.ibm.aix.osdevice/cmd_check_proc_stat.htmgrepコマンド
簡単に言うと検索するコマンド
参考:
https://eng-entrance.com/linux-command-grep#grepcatコマンド
concatnate:連結するの意
環境変数
定義は/etc/environmentに保存することで、サーバ全体に適用される。
環境変数の書き込みはvimコマンドを使用して行う。
環境変数を定義する場所はいくつかある。
左から順に優先される。
本番環境なら、/etc/environment ~/.bash_profile
ローカル環境なら、~/.bash_profile .env.development(gem'dotenv')gitignore関連の問題
<理由>
一度コミットしたファイルについては、その後.gitignoreに追加したとしてもGitの管理下から外されず、pushされてしまう。<対処方法>
(例)
・ターミナルで
> git rm --cached secrets.yml
を実行しGitで管理されないようにする。・secrets.ymlには直接キーを記述せず、環境変数を参照するようにする。
各5点
(補足)
環境変数とは、その端末のみからアクセスできる変数です。パスの指定や、今回のようにキーを保存するのに使われます。Linuxでは.bash_profileに記述をすることで、毎回環境変数を設定しなくても起動時にセットすることができます。
よく使う機能のため、ネット記事等を参考に整理しておくことをお勧めします。
本番環境で出品できなくなった
#current/log/production.rb ActionView::Template::Error (undefined method `category_id' for #<Item:0x00005623a4362ab8>):ローカルと本番環境のコードは同じに見える。
itemsテーブルにcategory_idがあることは確認。
悩むこと半日ぐらい。
最終的にインスタンスの再起動で治りました。
デプロイでハマったらインスタンス再起動しましょう。本番環境でrails c した時にエラー
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (13)本番環境でコンソールを使うときは
rails c productionらしい。
- 投稿日:2019-04-17T15:02:49+09:00
Railsチュートリアルで抑えておくべきポイント
minitestの書き方
なぜコントローラーのテストを実装するのか
- ルーティング通りにアクセスし、期待するページを表示出来ているかどうか
- 表示されたページの文言が期待するものであるかどうかrequire 'test_helper' class StaticPagesControllerTest < ActionDispatch::IntegrationTest def setup @base_title = "Ruby on Rails Tutorial Sample App" end test "should get home" do get static_pages_home_url assert_response :success #特定のHTMLタグが存在するかどうかをテストします #(この種のアサーションメソッドはその名から「セレクタ」と呼ばれることもある。 assert_select "title", "Home | #{@base_title}" end endsetupメソッドは、テストが実行される直前で呼ばれる。
→リファクタリングで使用。# この書き方は、application.html.rbが無い場合。railsを使うならこの方法は一般的では無い。 <% provide(:title, "Home") %> <!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> </head> <body> <h1>Sample App</h1>↓railsで実装するなら↓
app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head>app/views/static_pages/home.html.erb<% provide(:title, "Home") %> <h1>Sample App</h1> <p> This is the home page for the <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a> sample application. </p>provideの:titleが空の場合、無駄な「|」が入ってします。これを防ぐために、カスタムヘルパーを定義する。
app/helpers/application_helper.rbmodule ApplicationHelper # ページごとの完全なタイトルを返します。 # メソッド定義とオプション引数。 #引数にデフォルト値を含めている。 (この例のデフォルト値は空の文字列です)。このように指定すると、page_title変数に引数を渡すことも渡さないこともできます。引数を渡さない場合は、指定のデフォルト値(この場合は空の文字列)を渡すことができる。 def full_title(page_title = '') base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else page_title + " | " + base_title end end endカスタムヘルパーを定義し、以下のように修正をする。
application.html.erb<title><%= full_title(yield(:title)) %></title>Unixのプロセス
プロセスを確認できる。
$ ps auxプロセスの種類を指定してフィルタするには、psの結果をUnixの「パイプ」|でつないで、パターンマッチャーであるgrepに渡す。
※Springは「rails server」「rails console」「rake」コマンドが速くなる、Railsの新しいプリローダー$ ps aux | grep spring $ ps aux | grep serverプロセスid、略してpidを使い。不要なプロセスを排除するには、killコマンドでpidを指定し、Unixのkillコードを発行。
# 9はシグナル番号。 $ kill -9 [PID]開発中に動作がおかしくなったりプロセスがフリーズしていると思えたら、すぐにps auxで状態を確認し、kill -15 やpkill -15 -f <プロセス名>で整理してみましょう。
$ spring stop # spring stopが効かなかったら、下記で一気にspringプロセスをkillする。 $ pkill -9 -f spring盲点
シングルクォートは、入力した文字をエスケープせずに「そのまま」保持するときに便利。
>> '\n' # 'バックスラッシュ n' をそのまま扱う => "\\n" # ”\n”になると改行を意味してしまう。"\\n"をシングルクォートを使えば、実装が楽。オブジェクトとは (いついかなる場合にも) メッセージに応答するものです。
Ex,文字列のようなオブジェクトは、例えばlengthというメッセージに応答する# if文の違う書き方 puts "x is not empty" if !x.empty? #「!!」(「バンバン (bang bang)」と読みます) という演算子を使うと、そのオブジェクトを2回否定することになるので、どんなオブジェクトも強制的に論理値に変換できる >> !!nil => false >> !!0 => trueRubyのメソッドには「暗黙の戻り値がある」ことにご注意。これは、メソッド内で最後に評価された式の値が自動的に返されることを意味します (訳注: メソッドで戻り値を明示的に指定しなかった場合の動作です)
なので、以下のような場合は、returnが必要。def string_message(str = '') return "It's an empty string!" if str.empty? "The string is nonempty." endsplitメソッド(文字列を処理して配列を返す)
>> "foo bar baz".split # 文字列を3つの要素を持つ配列に分割する => ["foo", "bar", "baz"] >> "name".split('') => ["n", "a", "m", "e"] >> "name".split => ["name"] >> "fooxbarxbaz".split('x') => ["foo", "bar", "baz"]joinメソッド(splitの逆の処理。配列を処置して文字列を出力)
>> a => [42, 8, 17, 6, 7, "foo", "bar"] >> a.join # 単純に連結する => "4281767foobar" >> a.join(', ') # カンマ+スペースを使って連結する => "42, 8, 17, 6, 7, foo, bar">> a = %w[foo bar baz quux] # %wを使って文字列の配列に変換 => ["foo", "bar", "baz", "quux"] >> a = (0..9).to_a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >> ('a'..'e').to_a => ["a", "b", "c", "d", "e"] # 範囲(レンジ)と配列は蜜に関係している。 (1..5).each { |i| puts 2 * i } >> (1..5).map { |i| i**2 } # 「**」記法は冪乗 (べき乗) => [1, 4, 9, 16, 25] # mapとjoinは繋げられる def yeller(s) s.map(&:upcase).join end => :yeller yeller(['o','l','d']) => "OLD" # 以上ことを把握できれば、以下が理解できる。 ('a'..'z').to_a.shuffle[0..7].join >> p :name # 'puts :name.inspect' と同じ :name>> params = {} # 'params' というハッシュを定義する ('parameters' の略)。 => {} >> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" } => {:name=>"Michael Hartl", :email=>"mhartl@example.com"} >> params => {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}} >> params[:user][:email] => "mhartl@example.com"
- 投稿日:2019-04-17T15:02:49+09:00
Railsチュートリアルで押さえておくべきポイント
minitestの書き方
なぜコントローラーのテストを実装するのか
- ルーティング通りにアクセスし、期待するページを表示出来ているかどうか
- 表示されたページの文言が期待するものであるかどうかrequire 'test_helper' class StaticPagesControllerTest < ActionDispatch::IntegrationTest def setup @base_title = "Ruby on Rails Tutorial Sample App" end test "should get home" do get static_pages_home_url assert_response :success #特定のHTMLタグが存在するかどうかをテストします #(この種のアサーションメソッドはその名から「セレクタ」と呼ばれることもある。 assert_select "title", "Home | #{@base_title}" end endsetupメソッドは、テストが実行される直前で呼ばれる。
→リファクタリングで使用。# この書き方は、application.html.rbが無い場合。railsを使うならこの方法は一般的では無い。 <% provide(:title, "Home") %> <!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> </head> <body> <h1>Sample App</h1>↓railsで実装するなら↓
app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head>app/views/static_pages/home.html.erb<% provide(:title, "Home") %> <h1>Sample App</h1> <p> This is the home page for the <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a> sample application. </p>provideの:titleが空の場合、無駄な「|」が入ってします。これを防ぐために、カスタムヘルパーを定義する。
app/helpers/application_helper.rbmodule ApplicationHelper # ページごとの完全なタイトルを返します。 # メソッド定義とオプション引数。 #引数にデフォルト値を含めている。 (この例のデフォルト値は空の文字列です)。このように指定すると、page_title変数に引数を渡すことも渡さないこともできます。引数を渡さない場合は、指定のデフォルト値(この場合は空の文字列)を渡すことができる。 def full_title(page_title = '') base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else page_title + " | " + base_title end end endカスタムヘルパーを定義し、以下のように修正をする。
application.html.erb<title><%= full_title(yield(:title)) %></title>Unixのプロセス
プロセスを確認できる。
$ ps auxプロセスの種類を指定してフィルタするには、psの結果をUnixの「パイプ」|でつないで、パターンマッチャーであるgrepに渡す。
※Springは「rails server」「rails console」「rake」コマンドが速くなる、Railsの新しいプリローダー$ ps aux | grep spring $ ps aux | grep serverプロセスid、略してpidを使い。不要なプロセスを排除するには、killコマンドでpidを指定し、Unixのkillコードを発行。
# 9はシグナル番号。 $ kill -9 [PID]開発中に動作がおかしくなったりプロセスがフリーズしていると思えたら、すぐにps auxで状態を確認し、kill -15 やpkill -15 -f <プロセス名>で整理してみましょう。
$ spring stop # spring stopが効かなかったら、下記で一気にspringプロセスをkillする。 $ pkill -9 -f spring文法における盲点
シングルクォートは、入力した文字をエスケープせずに「そのまま」保持するときに便利。
>> '\n' # 'バックスラッシュ n' をそのまま扱う => "\\n" # ”\n”になると改行を意味してしまう。"\\n"をシングルクォートを使えば、実装が楽。オブジェクトとは (いついかなる場合にも) メッセージに応答するものです。
Ex,文字列のようなオブジェクトは、例えばlengthというメッセージに応答する# if文の違う書き方 puts "x is not empty" if !x.empty? #「!!」(「バンバン (bang bang)」と読みます) という演算子を使うと、そのオブジェクトを2回否定することになるので、どんなオブジェクトも強制的に論理値に変換できる >> !!nil => false >> !!0 => trueRubyのメソッドには「暗黙の戻り値がある」ことにご注意。これは、メソッド内で最後に評価された式の値が自動的に返されることを意味します (訳注: メソッドで戻り値を明示的に指定しなかった場合の動作です)
なので、以下のような場合は、returnが必要。def string_message(str = '') return "It's an empty string!" if str.empty? "The string is nonempty." endsplitメソッド(文字列を処理して配列を返す)
>> "foo bar baz".split # 文字列を3つの要素を持つ配列に分割する => ["foo", "bar", "baz"] >> "name".split('') => ["n", "a", "m", "e"] >> "name".split => ["name"] >> "fooxbarxbaz".split('x') => ["foo", "bar", "baz"]joinメソッド(splitの逆の処理。配列を処置して文字列を出力)
>> a => [42, 8, 17, 6, 7, "foo", "bar"] >> a.join # 単純に連結する => "4281767foobar" >> a.join(', ') # カンマ+スペースを使って連結する => "42, 8, 17, 6, 7, foo, bar">> a = %w[foo bar baz quux] # %wを使って文字列の配列に変換 => ["foo", "bar", "baz", "quux"] >> a = (0..9).to_a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >> ('a'..'e').to_a => ["a", "b", "c", "d", "e"] # 範囲(レンジ)と配列は蜜に関係している。 (1..5).each { |i| puts 2 * i } >> (1..5).map { |i| i**2 } # 「**」記法は冪乗 (べき乗) => [1, 4, 9, 16, 25] # mapとjoinは繋げられる def yeller(s) s.map(&:upcase).join end => :yeller yeller(['o','l','d']) => "OLD" # 以上ことを把握できれば、以下が理解できる。 ('a'..'z').to_a.shuffle[0..7].join >> p :name # 'puts :name.inspect' と同じ :name>> params = {} # 'params' というハッシュを定義する ('parameters' の略)。 => {} >> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" } => {:name=>"Michael Hartl", :email=>"mhartl@example.com"} >> params => {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}} >> params[:user][:email] => "mhartl@example.com">> class String # WordクラスはStringクラスを継承する >> # 文字列が回文であればtrueを返す >> def palindrome? >> self == self.reverse # selfは文字列自身を表します >> end >> end => :palindrome?selfはオブジェクト(インスタンス)をさす。
self == reverseと、selfの省略も可能。"aaa"はStringクラスのインスタンス
IE9への対応
念のため、以下のタグを
タグに入れた方が良い<!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]-->
画像の格納場所
assetのコンパイル対象にしたいならassets配下。
ブラウザのキャッシュコントロールのためのバージョン管理化に置かれなくていいならpublic配下に置く。基本的にはシステム側で作る画像はassets以下、ユーザー側のアップロードする画像はpublic配下に置いておく。ただ、表示速度を重視したい背景画像などは、public配下に置くと良い。
↓先頭に/(スラッシュ)をつけると、public配下になる。<%= image_tag '/images/hoge.png' %>yarnを使わず、gemでbootstrapを導入する方法
https://github.com/twbs/bootstrap-rubygem
# できるだけ、カスタムCSSは、一つのファイルで編集する $ touch app/assets/stylesheets/custom.scssapp/assets/stylesheets/custom.scss# 以下をimport @import "bootstrap";
- 投稿日:2019-04-17T14:13:39+09:00
【解決】ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ が出た時の対処法
開発実務1年目のボクがハマった勉強中には見なかったエラーの一つ
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)とかいうエラー
初めてこれにでくわした時は解決までに使った時間は3時間くらいだったと思います
なんせボクの開発現場ではみんなイヤホンをしているし、新人なのでエラーで相談は迷惑かなーーーと感じていたからですいま思えば新人だからこそエラーとか質問しやすいですよねw
ホントばかだったわ泣ボクの場合は
db:migrate
後に//localhost:3000に接続できなくなりMysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111)
エラーが吐かれました
調べてみるとmysqlを起動できれば解決しそうだという事まで突き詰めましたERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)の【解決コピペコード】
/var/run/mysqld/mysqld.sockの削除
$ sudo rm -f /var/run/mysqld/mysqld.sock/tmp/mysql.sockの削除
$ sudo rm -f /tmp/mysql.sockmysqlサーバーの再起動
$ sudo /etc/init.d/mysql startmysqlサーバー接続
$ mysql -u root -p以上です
接続できたらcontrol+Z
でmysqlから脱出してrails db:migrate
なりrails s -b 0.0.0.0
なりお好きにどうぞ
- 投稿日:2019-04-17T12:04:55+09:00
gem install mysql2のエラー対応
macでローカル環境を作るときに出やすいエラー
An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling. ERROR: While executing gem ... (Errno::EACCES) Permission denied @ rb_sysopen対応
$ sudo chown -R (ユーザ名):staff /Users/(ユーザ名)/.rbenv $ bin/bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include" $ bin/bundle install --path vendor/bundle
- 投稿日:2019-04-17T11:25:35+09:00
コールバックの種類
コールバック:登録や削除イベントの前後に挟む任意の処理のこと
コールバックの種類 代表的な用途 before_validation 検証前の値の正規化 after_validation 検証結果(エラーメッセージの正規化) before_save before_create
before_updatesaveのために裏側で行いたいデータ準備を行う。 検証エラーを出してもユーザー側からどうしようもない状態異常を防ぐために例外を出す。
after_save after_create
after_updateモデルの状態に応じて他のモデルの状態を変えるなどの、モデルの状態に連動した挙動を行わせる。 検証エラーを出してもユーザー側からどうしようもない状態異常を防ぐために例外を出す。
before_destroy 削除してOKかをチェックし、ダメなら例外を出すなどして防ぐ。 after_destroy そのモデルの削除に応じて他のモデルの状態を変えるといった連動した挙動を実現する。
- 投稿日:2019-04-17T11:13:22+09:00
devise NoMethodError (undefined method `utc'
こんなエラーが出てしまった場合
I, [2019-04-17T02:04:34.636864 #7612] INFO -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] Started GET "/users/sign_in" for 133.218.55.173 at 2019-04-17 02:04:34 +0000 I, [2019-04-17T02:04:34.637545 #7612] INFO -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] Processing by Users::SessionsController#new as HTML D, [2019-04-17T02:04:34.639131 #7612] DEBUG -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] (0.2ms) SET NAMES utf8mb4 COLLATE utf8mb4_bin, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 D, [2019-04-17T02:04:34.639915 #7612] DEBUG -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1 I, [2019-04-17T02:04:34.641703 #7612] INFO -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] Completed 500 Internal Server Error in 4ms (ActiveRecord: 1.0ms) F, [2019-04-17T02:04:34.642646 #7612] FATAL -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] F, [2019-04-17T02:04:34.642770 #7612] FATAL -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] NoMethodError (undefined method `utc' for Sat, 06 Apr 2019:Date): F, [2019-04-17T02:04:34.642858 #7612] FATAL -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] F, [2019-04-17T02:04:34.642973 #7612] FATAL -- : [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] devise (4.5.0) lib/devise/models/rememberable.rb:118:in `remember_me?' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] devise (4.5.0) lib/devise/models/rememberable.rb:143:in `serialize_from_cookie' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] devise (4.5.0) lib/devise/strategies/rememberable.rb:22:in `authenticate!' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/strategies/base.rb:54:in `_run!' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:369:in `block in _run_strategies_for' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:365:in `each' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:365:in `_run_strategies_for' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:335:in `_perform_authentication' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:110:in `authenticate' [18ca5a07-0693-4dd5-8be1-ac3c7c5ea47d] warden (1.2.8) lib/warden/proxy.rb:120:in `authenticate?'ローカルのクッキーを削除
- 投稿日:2019-04-17T10:50:15+09:00
bundle installすると"can't find gem bundler…"というエラーが発生
bundle installでエラーが出る
エラー内容
bundle install
を実行したところ、
find_spec_for_exe': can't find gem bundler (>= 0.a) (Gem::GemNotFoundException)
というエラーが発生してbundleinstallできない。原因
rubyとbundlerのバージョンに注意!
rubygemとbundlerのバージョンの組み合わせによって発生するエラーらしい。
解決法
- bundlerのバージョンを下げる
最新ではなく少し前のバージョンを指定してinstallしてあげる。
$ gem install bundler -v '1.17.3'そもそもの確認
- rubyとbundlerの場所を確認する。
rubyとbundlerが片方ローカルを参照していて、もう片方はグローバルを参照しているなど、そもそもローカルにgemが入っていなかったケース。
$ which ruby /Users/hoge/.rbenv/shims/ruby $ which bundler /Users/hoge/.rbenv/shims/bundler参考
- 投稿日:2019-04-17T09:19:56+09:00
【初心者向け】1番初めにやる、Ruby on Rails環境構築(Mac)
はじめに
Railsチュートリアル以降ずっとcloud9で開発してきましたが、cloud9上のエラーに時間を使ってしまったり、読み込みが遅かったり、業務に支障が出たりするので、流石にそろそろ1からしっかりと開発環境を作ってみようと思います。
環境構築
①Command Line Toolsインストール
コマンドラインツールとは、プログラミングの環境を構築したり実際にプログラムを実行したりする際に、コマンドを入力して操作ができるアプリケーション、CUI(キャラクターユーザーインターフェース)のことです。
(↔︎マウスなどで操作する通常アプリケーション:GUI(グラフィカルユーザーインターフェース))
Xcodeのバージョンが6.1以降の場合、Command Line Toolsは自動的にインストールされるので、Xcodeをダウンロードしていきます。
①Appleの「developerアカウント」にログイン
②『Download Tools』へ
③「Xcode」ダウンロードちなみにXcodeは、
・テキストエディタ
・インターフェースの作成(Interface Builder)
・デバッグ
・ビルド
・テスト
・シミュレーター(iOS Simulator)
・ソースの管理
などの必須機能を備えたものです。②Homebrewインストール
Homebrewとは、Mac OS Xオペレーティングシステム上でソフトウェアの導入を単純化するパッケージ管理システムのひとつです。
①あるかどうか確認(Xcodeが入ればHomebrewも入っているはず)
$ brew -v②念のためアップデート
$ brew update③rbenvインストール
rbenvとは、~/.rbenv/以下で、インストールした様々なRubyバージョンを管理し、状況に応じて必要になるRubyのバージョンを簡単に切り替えてくれるコマンドラインツールです。
①あるかどうか確認
$ rbenv -v②念のためアップデート
$ brew upgrade rbenv③無ければインストール
$ brew install rbenv ruby-build④Rubyの最新バージョンをインストール
①インストール可能なRubyのバージョンを確認
$ rbenv install --list②現時点で最新の「2.7.0-dev」を入れる
$ rbenv install 2.7.0-dev $ rbenv global 2.7.0-dev $ rbenv rehash③バージョンが反映されているか確認
$ ruby -v⑤Bundlerインストール
Bundlerとは、gem同士の互換性を保ちながらパッケージの種類やバージョンを管理してくれるgemです。
複数人、または複数環境で開発を行う際、各環境で使用するものに合わることができます。Ruby2.6.0よりBundlerは標準添付されてるので、上記の通りやっていれば既にインストールされているはずです。
①念のため確認
$ bundle -v②念のためアップデート
$ gem update bundler③無ければインストール(Ruby2.5.5以前を使用していた場合、等)
$ gem install bundler⑥MySQLインストール
(SQLiteを使用する場合この設定は不要です)
MySQLとは、世界で最も利用されているデータベース管理システムです。
LAMP環境(「Linux」+「Apache」+「MySQL」+「PHP(またはRuby)」)でサーバーを構築する企業が多く、よく利用されています。
①MySQLをインストール
$ brew install mysql②起動
$ mysql.server start Starting MySQL . SUCCESS!⑦Railsインストール
最後です。
GemfileにRailsを加え、インストールしていきます。
これができて、晴れて画面表示されます。①作業するディレクトリを作成
$ mkdir ~/workspace $ cd ~/workspace②Rubyのバージョンを指定
$ rbenv local 2.7.0-dev作業ディレクトリに.ruby-versionファイルが作成される
③Gemfileを作成する
$ bundle init④Gemfile内の「# gem "rails"」のコメント解除
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails"⑤Railsをインストール
$ bundle install --path=vendor/bundle $ bundle exec rails -v Rails 5.2.3⑥Railsアプリ作成
$ bundle exec rails new test_app⑦Webサーバー起動
$ rails server⑧http://localhost:3000/ へアクセス
下記の画面が表示されれば成功です。
⑨※サーバーが立ち上がらない
railsはしっかり入っているのに、rails serverを実行すると
$ rails server Rails is not currently installed on this system. To get the latest version, simply type: $ sudo gem install rails You can then rerun your "rails" command.と出て実行してくれませんでしたが、
下記を実行した後に無事動くようになりました。
$ gem install railties $ rbenv rehash上の画像が表示されました!!
参考
最速!MacでRuby on Rails環境構築
Ruby初学者のRuby On Rails 環境構築【Mac】
railsコマンドが使えないときにやったこと
- 投稿日:2019-04-17T03:24:23+09:00
RailsにRspecをいれてモデルのテストを書いてみよう[初心者向け]
こんにちは。
エンターシェアでエンジニアとして働いているじゅん(@BoNingennnN)です。Railsでは標準でminitestが入ってきます。
しかし、弊社ではminitestを使わずRSpecを使っています。
また、個人プロジェクトでもRSpecを使っています。今回はRailsプロジェクトにRSpecを導入する方法を説明し、そしてテストの手始めとしてモデルのテストを書いていこうと思います!
まずはRailsプロジェクトにRSpecを導入しよう
既存のプロジェクトにRspecを導入する際には、既存のtestを削除する必要があります。
まずtestディレクトリを削除しましょう。続いてRspecのgemをいれていきます
Gemfilegroup :development, :test do gem 'rspec-rails' endbundle installもしまだ既存のプロジェクトでtest用のdbを作成していない場合はそれを作成します。
config/database.ymlにtest用の記述があることを確認したら以下のコマンドを打ちましょうrails db:createこれでtest用のdbの作成が完了です。
続いてRspecの導入を進めます。
以下のコマンドでRspecの設定ファイルなどを生成しましょう。rails g rspec:installここはお好みになりますが、testの実行結果が見やすいように以下の記述を.rspec内に書いておくといいです。
.rspec--format documentationこれでRspecの導入は完了しました!
早速以下のコマンドを実行してテストを実行しましょう。bundle exec rspec結果は、、
No examples found. Finished in 0.00079 seconds (files took 0.25041 seconds to load) 0 examples, 0 failures大成功です。
まだテストを書いていないので、0 expamleです。
exampleはテストの数、failuresは通らなかったテストの数を返します。
まだテストを書いていないので、もちろんexample、failures共に0です。では続いて超初歩的なモデルのテストを書いていきましょう。
モデルのテストをRspecで書こう
ここからはモデルのテストを書きます。
ここではすでにPostモデルがあると仮定します。
(ここは各自のアプリケーションにあるモデルと置き換えて考えてください?♂️)post.rbclass Post < ApplicationRecord validates :title, presence: true, length: {maximum: 20} validates :content, presence: true def content_length self.content.length end endこんな単純なモデルはありえないですが、入門ということで簡単なモデルにしました。
既存のモデルのテストを作るには以下のコマンドを実行します。
rails g rspec:model postすると以下のファイルが生成されます。
spec/models/post_spec.rbrequire 'rails_helper' RSpec.describe Post, type: :model do pending "add some examples to (or delete) #{__FILE__}" endここで先ほどと同様にtestを実行してみましょう。
bundle exec rspecすると先ほどとは異なる出力が見られます。
Pending: (Failures listed here are expected and do not affect your suite's status) 1) Post add some examples to (or delete) /Users/junya/workspace/myprojects/rails-rspec-test/spec/models/post_spec.rb # Not yet implemented # ./spec/models/post_spec.rb:4 Finished in 0.00684 seconds (files took 4.16 seconds to load) 1 example, 0 failures, 1 pending注目して欲しいのは、exmapleが0から1に変わった部分です。
これは先ほど生成したpost_spceを生成したからです。
pendingとなっているのは、「このテストは一旦後回しにしますよー」という意味です。
生成されるspecファイルは、初期でpendingとなっています。
この部分を実際に書き換えていきましょう!と、その前にまずモデルテストでテストすべきことを書いていきます。
基本的には、そのモデルのバリデーションのテストを書きます。
さらに、そのモデルがインスタンスメソッドを持っているのであればそのテストも書きますし、クラスメソッドを持っていればクラスメソッドのテストも書きます。また、scopeに関するテストももちろん必要です。今回の例だと、バリデーションとインスタンスメソッドがあるので、それぞれのテストを書いていきます。
バリデーションのテストを書いてみる
早速バリデーションのテストを書いていきましょう。
post_spec.rbrequire 'rails_helper' RSpec.describe Post, type: :model do it "is valid with title and content" do post = Post.new(title: "test", content: "testcontent") expect(post).to be_valid end end先ほどpendingと書かれていた部分を削除し、実際にテストを書いてみました。
テストを書く際にはit "テストの内容の説明" do テストの処理 endという形で書きます。
モデルテストを書く際には、まずちゃんとバリデーションが通ること(be_valid)をテストします。
ここでテストを実際に実行してみましょう。bundle exec rspec出力は以下のようになります。
. Finished in 0.01384 seconds (files took 3.45 seconds to load) 1 example, 0 failures見事に1exampleが実行され、failure(テストの失敗)は0です!
ここで一度テストをわざと失敗させてみましょう。先ほど作成したテストの中身を少し書き換えてみます。
post_spec.rbrequire 'rails_helper' RSpec.describe Post, type: :model do it "is valid with title and content" do post = Post.new(title: "test", content: "testcontent") expect(post).not_to be_valid #toからnot_toに変更 end endそしてテストを実行してみると、、、
F Failures: 1) Post is valid with title and content Failure/Error: expect(post).not_to be_valid expected #<Post id: nil, title: "test", content: "testcontent", created_at: nil, updated_at: nil> not to be valid # ./spec/models/post_spec.rb:6:in `block (2 levels) in <top (required)>' Finished in 0.0629 seconds (files took 3.57 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/models/post_spec.rb:4 # Post is valid with title and content見事に1example 1failureになっています!
テストが失敗したことがわかるかと思います。
こんな感じで、もし通らないテストがあるとちゃんと表示されます。先ほど変更した部分を元に戻したら、バリデーションテストの続きを書いていきましょう。
今回のPostモデルには3つのバリデーションがあります。
・titleが存在すること
・titleの最大文字数は20文字
・contentが存在することそれらのバリデーションのテストを実際に書いていきます
post_spec.rbit "is invalid without title" do post = Post.new(title: nil) post.valid? expect(post.errors[:title]).to include("can't be blank") end it "is invalid withoug content" do post = Post.new(content: nil) post.valid? expect(post.errors[:content]).to include("can't be blank") endtitleとcontentのpresence: trueのバリデーションのテストをまず書きました。
もしtitleがnilなら「titleは空欄じゃダメですよ」っていうエラーがあるよね、ということをテストしています。(contentも同様)
このパターンはバリデーションのテストの際によく出てくるパターンです。続いて文字数の部分のテストを書きます。
post_spec.rbit "is invalid when title is more than 20 characters" do post = Post.new(title: ("a" * 21)) post.valid? expect(post.errors[:title]).to include("is too long (maximum is 20 characters)") end21文字だとエラーが出るよね、ということをテストしています。
本来だったら20文字の場合はエラーだなくてvalidだよねというのもテストした方が良さそうですが、ずいぶん長くなってきたので割愛します。以上がバリデーションのテストです。
バリデーションのテストは結構パターンがあるので慣れればすんなり書けます。
また、バリデーションをうっかり忘れていた、なんてことも気付けたりしますので、そういう意味でもバリデーションテストはしっかり書いておいたほうがいいです。インスタンスメソッドのテストを書いてみる
続いてインスタンスメソッドのテストも書いてみます。
今回の例だと、post.rbdef content_length self.content.length endこのcontent_lengthというインスタンスメソッドのテストを書きます。
インスタンスメソッドやクラスメソッドでは、適当に入力する値をいれ、その出力が正しいかをテストします。
と言ってもよく分からないかもしれないので、実際にコードを書いていきましょう。post_rspec.rbit "returns length of content" do post = Post.create(title: "test", content: ("a" * 100)) expect(post.content_length).to eq(100) endなんとなく見ればわかるかと思いますが、contentが100文字なpostを作成し、
post.content_lengthが100と等しいことをテストしています。
これは非常に簡単な例ですが、複雑になってきても基本はこれです。
こんな感じでどんどんインスタンスメソッドやクラスメソッドのテストも書いていきましょう!!さいごに
本当はもっと複雑なメソッドのテスト等も書きたかったのですが、最初から難しいめのテストを書くと挫折してしまう可能性があると思ったので、今回は超簡単なものだけにしました。
(本当はただ書くのが面倒くさかっただけかもです。笑)今回の例は初歩の初歩で、factory_botも使っていませんし、モデル以外のテストも全く出てきませんでした。
実際のプロジェクトでテストを書くとなると、学ぶべきことは他にも色々ありますが、とりあえずはこのモデルの基本的なテストを書けるようになっておけばあとは色々ググりながらどうにかなるかと思います!もし今担当しているプロジェクトや、個人開発のプロジェクトでテストを書いていないのであれば、まずはモデルテストから書いてみてください!
- 投稿日:2019-04-17T01:44:41+09:00
【学習アウトプット3】has_secure_passwordとvalidates :password, presence: trueの違い
背景
has_secure_passwordを設定したUserモデル
user.rbclass User < ApplicationRecord has_secure_passwordが、以下のテスト
user_controller_test.rbtest "password should be exist when create" do @user.password = " " assert_not @user.valid? endで引っかかってしまう問題に悩んでいました。
(has_secure_passwordは空白にvalidationがかかると思っていたため https://qiita.com/Shantti-Y/items/19ea23b81f3421063fc5)validates :password, presence: trueをつけるとテストをパスします。
じゃあ、has_secure_passwordのデフォルトvalidationとは一体...結論
Rails 4.2から以下のように変更されていたとのことです。
has_secure_password がデフォルトで空白のパスワードを許容するようになりました (例: 空白スペースのみのパスワード)。 https://railsguides.jp/4_2_release_notes.html
空白を許可したくない場合は別途
validates :password, presence: true
等の追加が必要みたいです。
- 投稿日:2019-04-17T00:56:51+09:00
devise(メール承認付き)のパラメータをコンソールで直接編集する
deviseで新規userを登録する
user.skip_confirmation
でメール承認をスキップできる。user = User.new(email: "hogehoge@mail.co.jp", password: "hogehoge") user.skip_confirmation! user.save既存のuserを編集する
user.reconfirmation
でメール承認をスキップする。user = User.find_by(email: "hogehoge@mail.co.jp") user.email = "fugafuga@mail.com" user.skip_reconfirmation! user.save
- 投稿日:2019-04-17T00:33:01+09:00
Rubyは最後に評価された式が戻り値になるというが、どのif文にも入らなかったらどうなるのか
経緯
- Rubyを学び始めた頃のコードを直しているのですが、Javaエンジニアだったためかメソッド内に無駄なreturn文が多いです。
- 直す最中に表題の件について気になったので、
Rails c
を使って試し、またRailsのビューから呼ばれた時はどうなるのかについても試してみました。修正前
- ひどい書き方ですね。。。
game.rbdef get_msg msg = "" if self.gameset_flag if get_sum_top == get_sum_bottom #同クラス内の別のインスタンスメソッドを呼んでいます msg = "(引き分け)" elsif !self.top6 msg = "(5回コールド)" elsif !self.top7 msg = "(6回コールド)" elsif !self.top8 msg = "(7回コールド)" elsif !self.top9 msg = "(8回コールド)" end end return msg end修正後
- このメソッドをビューから呼んだ時に、どのif文にも入らなかった場合は、ちゃんと空文字で画面表示できるのか気になっていました。
game.rbdef get_msg if self.gameset_flag if get_sum_top == get_sum_bottom #同クラス内の別のインスタンスメソッドを呼んでいます "(引き分け)" elsif !self.top6 "(5回コールド)" elsif !self.top7 "(6回コールド)" elsif !self.top8 "(7回コールド)" elsif !self.top9 "(8回コールド)" end end end
Rails c
で動かしてみる
- コード修正は今回の主旨ではないため、修正後のコードのみで試します。
irb(main):001:0> game = Game.new (出力省略) irb(main):002:0> game.get_sum_top => 0 irb(main):003:0> game.get_sum_bottom => 0 irb(main):004:0> game.gameset_flag = false => false irb(main):005:0> game.get_msg => nil irb(main):006:0> game.gameset_flag = true => true irb(main):007:0> game.get_msg => "(引き分け)"
- どのif文にも入らない場合は、最初のif文の条件式が最後に評価されたことになります。
- つまり
self.gameset_flag
はnil
ということでnil
が返って来ているのがわかります。画面表示はどうなる
- 実際の画面キャプチャは貼れないのですが、結論としては問題ありませんでした(空文字がreturnされていた頃と表示に変化なし)。
- つまり、修正前のコードのように、どのif文にも入らなかった時のための変数の初期化は不要ということになります(もちろん設計上空文字を返却する必要がある場合は、メソッドの最終行に空文字を書いて、空文字が最後に評価されるようにすると良いと思います)。
参考