ためすう
Rails5 の css で画像を設定する
2019-06-11やったこと
Rails5 の css で画像を設定します。
今回 production 環境で試します。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
画像を下記に配置します
app/assets/images/sample.png
app/views/tasks/new.html.erb
<div id="main">
dddd
</div>
app/assets/stylesheets/tasks.scss
#main {
background-image: image-url('sample.png')
}
config/environments/production.rb
# config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server.enabled = true
↑ Webサーバから静的ファイルを読み込むことができるようにします。
$ RAILS_ENV=production bin/rails assets:precompile
↑ プリコンパイルして、ファイルを作成します。
参考
Rails5 で自作ミドルウェアを作ってみる
2019-06-11やったこと
Rails5 で自作したミドルウェアを読み込んで使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
現在のミドルウェア
$ bin/rails middleware
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
run Sample2::Application.routes
lib/middlewares/my_middleware.rb
class MyMiddleware
def initialize(app)
@app = app
end
def call(env)
if env['PATH_INFO'] == '/tasks/new'
Rails.logger.debug('path is /tasks/new')
res = @app.call(env)
else
Rails.logger.debug('path is other')
res = @app.call(env)
end
res
end
end
config/application.rb
require './lib/middlewares/my_middleware'
...
module Sample2
class Application < Rails::Application
...
config.middleware.use ::MyMiddleware
end
end
$ bin/rails middleware | grep My
use MyMiddleware
参考
Ruby でインターフェースクラスを作る
2019-06-10やったこと
Ruby では下記のようなインターフェースがありません。
そこで、Ruby でも似たようなことを実現する方法を試してみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
継承で実現する
main.rb
class MyInterface
def hoge
raise NotImplementedError.new("#{self.class}##{__method__} を実装してください")
end
end
class SampleFailed < MyInterface
end
class SampleSuccess < MyInterface
def hoge
p "#{self.class}##{__method__}が実装されている!"
end
end
SampleSuccess.new.hoge
SampleFailed.new.hoge
出力結果
$ ruby main.rb
"SampleSuccess#hogeが実装されている!"
Traceback (most recent call last):
1: from main.rb:17:in `<main>'
main.rb:3:in `hoge': SampleFailed#hoge を実装してください (NotImplementedError)
Module で実現する
main2.rb
module MyInterface
def hoge
raise NotImplementedError.new("#{self.class}##{__method__} を実装してください")
end
end
class SampleFailed
include MyInterface
end
class SampleSuccess
include MyInterface
def hoge
p "#{self.class}##{__method__}が実装されている!"
end
end
SampleSuccess.new.hoge
SampleFailed.new.hoge
出力結果
$ ruby main2.rb
"SampleSuccess#hogeが実装されている!"
Traceback (most recent call last):
1: from main2.rb:20:in `<main>'
main2.rb:3:in `hoge': SampleFailed#hoge を実装してください (NotImplementedError)
参考
Rails5 で System Spec を使ってみる
2019-06-10やったこと
System Spec を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
$ gem list | grep rspec-rails
rspec-rails (3.8.2)
調査
System Spec とは
Rails の SystemTestCase を Rspec から利用できるようにしたもの
SystemTestCase は E2E テストを実行することができます。
使ってみる
ファイル準備
$ mkdir spec/system
$ touch spec/system/tasks_spec.rb
app/views/tasks/new.html.erb
<button onclick="if (confirm('ok???')) { alert('pushed ok!!!'); }">
テストボタン
</button>
spec/system/tasks_spec.rb
require 'rails_helper'
RSpec.describe 'Tasks', type: :system do
it 'js test' do
visit '/tasks/new'
click_button('テストボタン')
expect(page.driver.browser.switch_to.alert.text).to eq 'ok???'
page.accept_confirm
expect(page.driver.browser.switch_to.alert.text).to eq 'pushed ok!!!'
page.accept_alert
end
end
System Spec を実行
$ rails spec spec/system/tasks_spec.rb
参考
やったこと
JavaScript の encodeURI と encodeURIComponet を使ってみます。
確認環境
navigator.userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
調査
encodeURI を使う
encodeURI("/hogehoge/index?a=22&b=ああ")
"/hogehoge/index?a=22&b=%E3%81%82%E3%81%82"
エスケープされない文字: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ‘ ( ) #
encodeURIComponent を使う
encodeURIComponent("/hogehoge/index?a=22&b=ああ")
"%2Fhogehoge%2Findex%3Fa%3D22%26b%3D%E3%81%82%E3%81%82"
encodeURIComponent は次を除く全ての文字をエスケープします : アルファベット、10進数字、- _ . ! ~ * ‘ ( )
encodeURIComponent は、URI の構成要素となる文字列 をエスケープするものです。
参考
jq を使って json を整形してみる
2019-06-09やったこと
jq コマンドを使って、json を見やすいように整形してみます。
確認環境
Mac High Sierra (10.13.6)
調査
jq のインストール
$ brew install jq
json を出力する
jq なし
$ echo '{"root":[{"group1": [1]},{"group2": [3,4,5]}]}'
{"root":[{"group1": [1]},{"group2": [3,4,5]}]}
読みにくいですね。
jq あり
$ echo '{"root":[{"group1": [1]},{"group2": [3,4,5]}]}' | jq
{
"root": [
{
"group1": [
1
]
},
{
"group2": [
3,
4,
5
]
}
]
}
階層が分かりやすくなりました。
ちなみに json が壊れてたりすると、下記のようなエラーが出ます。
$ echo '{"root"' | jq
parse error: Unfinished JSON term at EOF at line 2, column 0
参考
アジャイルソフトウェア開発の奥義 第4章 テスティング
2019-06-08「アジャイルソフトウェア開発の奥義」の読書メモです。
時々、個人の見解入りです。
ユニットテストを書くという行為は、機能検証というよりも設計に近い行為である。また、ドキュメント作成に近い行為であるとも言える。
テストを最初に書くという行為は、設計上の判断をふるいにかける行為でもある。
テスティングフレームワークに頼らない場合、本章にある通り、設計を気にする必要がある。
Ruby on Rails などの場合、テスティングフレームワーク の機能がリッチだと思うので
テスト実行時に、テスト対象の処理を上書きする形にすればテストは実現できそうである。
Mock Object パターンも、テスト専用の処理をどこに、どうやって書くかの1つの選択肢。
テスティングフレームワークに頼りすぎると、基盤の移行をする際、選択肢が少なくなる可能性があるのがデメリットと考える。
根底にある考えは理解する必要があると思うが、現実に即して考えると全部真似する必要はないと思う。
Active Support の concern を使ってみる
2019-06-08やったこと
Active Support の concern を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
concern を使う主な理由
mix-in で同じことをやると記述が複雑になりますが、concern を使えば簡潔に書くことができます。
また、複雑な依存関係を考慮しなくて良くなります。
確認 (concern なし)
test.rb
module Hoge2
def self.included(base)
base.class_eval do
def self.method_injected_by_hoge2
'method_injected_by_hoge2'
end
end
end
end
module Hoge1
def self.included(base)
base.method_injected_by_hoge2
end
end
class Sample
include Hoge2
include Hoge1
end
p Sample.method_injected_by_hoge2
ここで、include Hoge2 がないと下記のエラーで落ちます。
Traceback (most recent call last):
3: from ruby-mix-in.rb:18:in `<main>'
2: from ruby-mix-in.rb:19:in `<class:Sample>'
1: from ruby-mix-in.rb:19:in `include'
test.rb:13:in `included': undefined method `method_injected_by_hoge2' for Sample:Class (NoMethodError)
確認 (concern あり)
test.rb
require 'active_support/concern'
module Hoge2
extend ActiveSupport::Concern
included do
def self.method_injected_by_hoge2
'method_injected_by_hoge2'
end
end
end
module Hoge1
extend ActiveSupport::Concern
include Hoge2
included do
self.method_injected_by_hoge2
end
end
class Sample
include Hoge1
end
p Sample.method_injected_by_hoge2
Sample クラスは Hoge1 だけ include すれば良くなりました。
参考
やったこと
Selenium に関する警告が出るようになったので修正します。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
メッセージ
2019-06-08 14:23:23 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
書いてある通りですが、
[非推奨] Selenium::WebDriver::Chrome#driver_path=
[推奨] Selenium::WebDriver::Chrome::Service#driver_path
みたいです。
修正
Today I got the same issue and the reason of that was a gem called chromedriver-helper in Gemfile, I just removed this gem and after I ran this command: bundle install
参考リンクを見ると、chromedriver-helper を削除したら、解決できそうです。
また、
If your code is using selenium, perhaps with the Watir gem, use the Webdriver gem instead of chromedriver-helper now. gem ‘webdrivers’, ‘~> 3.0’
chromedriver-helper の代わりに、webdrivers を使うと幸せになれるかもしれない。
とあるのでやってみます。
Gemfile
- gem 'chromedriver-helper'
+ gem 'webdrivers', '~> 3.0'
$ bundle install
これで警告が出なくなりました。
参考
hashdiff に関する警告が出たので修正する
2019-06-08やったこと
WebMock をインストールしたら、hashdiff に関する警告が出るようになったので修正します。
エラーで止まるわけではないので、ワーニングのようです。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
メッセージ
The HashDiff constant used by this gem conflicts with another gem of a similar name. As of version 1.0 the HashDiff constant will be completely removed and replaced by Hashdiff. For more information see https://github.com/liufengyun/hashdiff/issues/45
- 定数で似ているものが使われている
- HashDiff -> Hashdiff に置き換えられる
修正
メッセージのリンクを辿ると、下記に解決策がありました。
Conflicts with hash_diff
· Issue #45 · liufengyun/hashdiff
Gemfile
gem 'hashdiff', ['>= 1.0.0.beta1', '< 2.0.0']
$ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/.
You have requested:
hashdiff >= 1.0.0.beta1, < 2.0.0
The bundle currently has hashdiff locked at 0.4.0.
Try running `bundle update hashdiff`
If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`
update してみます
$ bundle update
(これで該当の警告は出なくなりましたが、新しい警告が出るようになりました。)