rspecで時間操作をする
今まではtimecop使ってたんだけど、細かい制御までは特にする必要もなかったので ActiveSupport::Testing::TimeHelpers を使ってみる
spec/rails_helper.rbに以下を追記
# This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' require 'webdrivers' require 'email_spec' require 'email_spec/rspec' Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f } # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines. begin ActiveRecord::Migration.maintain_test_schema! rescue ActiveRecord::PendingMigrationError => e puts e.to_s.strip exit 1 end RSpec.configure do |config| config.use_transactional_fixtures = true config.infer_spec_type_from_file_location! # Filter lines from Rails gems in backtraces. config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") config.include ActiveJob::TestHelper config.include ActiveSupport::Testing::TimeHelpers # <-- 追記 end
使いたい箇所で travel_toで囲む
context "Sample" do it do travel_to('2020-1-1 0:00'.to_time) do # do test end end end
aroundを使って広範囲に反映する
context "Sample" do around do |e| travel_to('2020-1-1 0:00'.to_time) { e.run } end it do # do test end it do # do test end end
Rails5.2からRails6.0へアップグレードする
Gemを更新
source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -gem 'rails', '~> 5.2.4.3' +gem 'rails', '~> 6.0.3.2' gem 'pg' gem 'puma' gem 'turbolinks', '~> 5'
bundle update rails
アップデートタスクを実行
rails app:update
アップデートタスクで気になる変更はそれほどなかったが、ActiveStorageを使っていた場合はデータベースのマイグレーションファイルが作らているのでdb:migrateをする必要がある 使ってなければマイグレーションファイルは消してもよさそう(消さなくても問題ないけど)
必要があれば追加された config/initializers/new_framework_defaults_6_0.rb を編集する
# Be sure to restart your server when you modify this file. # # This file contains migration options to ease your Rails 6.0 upgrade. # # Once upgraded flip defaults one by one to migrate to the new default. # # Read the Guide for Upgrading Ruby on Rails for more info on each option. # Don't force requests from old versions of IE to be UTF-8 encoded. # Rails.application.config.action_view.default_enforce_utf8 = false # Embed purpose and expiry metadata inside signed and encrypted # cookies for increased security. # # This option is not backwards compatible with earlier Rails versions. # It's best enabled when your entire app is migrated and stable on 6.0. # Rails.application.config.action_dispatch.use_cookies_with_metadata = true # Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. # Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false # Return false instead of self when enqueuing is aborted from a callback. # Rails.application.config.active_job.return_false_on_aborted_enqueue = true # Send Active Storage analysis and purge jobs to dedicated queues. # Rails.application.config.active_storage.queues.analysis = :active_storage_analysis # Rails.application.config.active_storage.queues.purge = :active_storage_purge # When assigning to a collection of attachments declared via `has_many_attached`, replace existing # attachments instead of appending. Use #attach to add new attachments without replacing existing ones. # Rails.application.config.active_storage.replace_on_assign_to_many = true # Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. # # The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob), # will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions. # If you send mail in the background, job workers need to have a copy of # MailDeliveryJob to ensure all delivery jobs are processed properly. # Make sure your entire app is migrated and stable on 6.0 before using this setting. # Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" # Enable the same cache key to be reused when the object being cached of type # `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) # of the relation's cache key into the cache version to support recycling cache key. # Rails.application.config.active_record.collection_cache_versioning = true
ディスク容量チェックの動作確認のため空ファイルを作る
サーバーにsshでつないで下記コマンドを実行すると10GBのファイルが作られる
dd if=/dev/zero of=tempfile1 bs=1M count=10000
countのとこの数字を変更して作りたいファイルのサイズは調整する
Railsのroutingでパラメータにドットを許容する
paramsにドットが入るとデフォルトではRouting Errorが返される
resources :users, constraints: {id: /[-a-zA-Z0-9.\-_\+]+/}
このように指定すると id にアルファベットとマイナスとドットとアンダーバーとプラスを許容できる
複数モデルでdeviseを利用するときに特定のモデルだけauthentication_keysを変更したい
ログインに利用するキーを変更するには通常 config/initializers/devise.rbの中の
# ==> Configuration for any authentication mechanism # Configure which keys are used when authenticating a user. The default is # just :email. You can configure it to use [:username, :subdomain], so for # authenticating a user, both parameters are required. Remember that those # parameters are used only when authenticating and not when retrieving from # session. If you need permissions, you should implement that in a before filter. # You can also supply a hash where the value is a boolean determining whether # or not authentication should be aborted when the value is not present. # config.authentication_keys = [:email]
ここの config.authentication_keys = [:email]
を変更すればよいが、ここを変更すると全てのモデルに反映されてしまう
特定のモデルだけの場合は以下のようにdeviseのoptionとして指定すればよい
class Customer < ApplicationRecord devise :database_authenticatable, authentication_keys: [:organization_id, :email] # 企業IDとメールアドレスでログインをする def self.find_for_database_authentication(warden_conditions) email = warden_conditions[:email].to_s.downcase.strip find_by(email: email, organization_id: warden_conditions[:organization_id]) end end
after_saveで項目の値が変わっていたかどうかを確認したい
saved_changeや(項目名)_previous_changeを使って変更を確認する
user = User.new user.email = "test@example.com" user.save p user.email_previous_change
["", "test@example.com"]
class User < ApplicationRecord after_save :do_somothing_if_email_changed def do_somothing_if_email_changed if self.email_previous_change.uniq.length > 1 # do something end end end