30歳パパエンジニアのアウトプット帳

30歳に突入した1児のパパエンジニアのブログ

【訂正】Rails5.1のconfig.load_defaultsを利用しているとconfig/initializers/new_framework_defaults.rbの値は上書きされない(activerecord-session_store利用時)

訂正しました (2017/10/18)

どうやら、上書きされないのではなくて、下記の現象が起きていたようです。

[Rails]... | 日々雑記


まだどれが影響を与えているのかわかってないですが、他のRailsアプリだとちゃんと上書きされていました。。。

このアプリだけなにやってもActiveRecord::Base.belongs_to_required_by_defaultがnilになっていました。

> ActiveRecord::Base.belongs_to_required_by_default
=> nil
> Rails.application.config.active_record.belongs_to_required_by_default
=> false

さらに追記

どうやらactiverecord-session-storeが原因みたい。

activerecord-session-storeを利用していると、config.load_defaults 5.1ありでconfig/initializers/new_framework_defaults.rbにRails.application.config.active_record.belongs_to_required_by_default=falseを指定した場合は上書きされない。

> ActiveRecord::Base.belongs_to_required_by_default
=> true
> Rails.application.config.active_record.belongs_to_required_by_default
=> false

config/application.rbにconfig.active_record.belongs_to_required_by_default=falseを書いた場合はちゃんと両方falseになるが、config/initializers/new_framework_defaults.rbに書くとなぜか今回の事象になる。。

[config/application.rb]

module アプリ名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.1
    config.active_record.belongs_to_required_by_default = false # ここに直接書くとちゃんと上書きされる

rails c
> ActiveRecord::Base.belongs_to_required_by_default
=> false
> Rails.application.config.active_record.belongs_to_required_by_default
=> false

activerecord-session_storeのバージョン

GIT
  remote: https://github.com/rails/activerecord-session_store.git
  revision: b5e7da210c937c0aa580b8094b64019cef20e95a



ちょっとはまったのでメモ。


[config/application.rb]

module アプリ名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.1

のように、config.load_defaults 5.1を記述すると

config/initializers/new_framework_defaults.rbにbelongs_to_required_by_defaultなどの設定を変更する記載があっても上書きはされない。

[config/initializers/new_framework_defaults.rb]

# Require `belongs_to` associations by default. Previous versions had false.
Rails.application.config.active_record.belongs_to_required_by_default = false

config/application.rbの後にconfig/initializers/new_framework_defaults.rbも読まれているので上書きされるのかと思っていたけど違うみたい。


下記にある通り、Railsが推奨する設定を使う場合にconfig.load_defaultsを利用するので上書きできなくてもいいんだと思うけど。

Rails 5.1で追加されたconfigまとめ | 日々雑記

Railsのinculudesについて

以前は普通にincludesを使っていたけど、includes(:books).references(:books)みたいに書くようになってからちょっと疑念を抱いていた。

そして、確かr7kamuraさんのamakanの実装についての記事でpreloadとかを使っていて、やっぱりpreloadやeager_loadを明示的に使ったほうがぱっと見分かりやすいのでは?と思って、includesを使わないように意識していた。


そんな中、下記の記事を最近読んだ。

techracho.bpsinc.jp

あぁ、やっぱりincludes(:books).references(:books)みたいに書くの冗長だと思っている人いるよね。 (includes支持者ももちろんいるみたいだけど


これからも、やはりincludesは極力使わずにpreloadやeager_loadを使うようにしていこうと思った。



なお、未だにpreloadやeager_loadなどが自信無くなるので下記によくお世話になってる。

qiita.com

cancancaでAbilityクラスにcurrent_user以外の引数を渡す方法

Cancan(Cancancan)使ってて、今までは下記みたいにuserさえあればよかったけど、ある時sessionのある値をAbilityクラスに渡したくなった。

class Ability
  include CanCan::Ability

  def initialize(user) ←(user, other_param)みたいにしたい!
    ・・・
  end
end

ぐぐっていると下記を見つけた。

github.com

なので、そこにあるようにapplication_controller.rbでcurrent_abilityをオーバーライドすればOK。

react-railsとreact_on_railsについてのメモ

個人用の調べたことや思ったことメモ。

RailsでReactを利用するのに使われる2大Gem。 どちらもSSRに対応している。

webpackerでreactやるんではダメなん?

webpacker:install:reactのこと。 やれなくはないと思う。

しかし、今回はSPAではなく一部分に導入(ボタン等)したかったので、react_componentのようなヘルパーメソッドがほしかった(部分適用が楽)

下記のようにやる必要があるので、部分適用で箇所が多くなるとツライと思う。。

document.addEventListener("DOMContentLoaded", e => {
  ReactDOM.render(<Hello name="React" />, document.getElementById("ターゲットのid"))
})

react-rails

https://github.com/reactjs/react-rails

  • react登場の初期の頃からある認識
  • execjs依存
  • 単体利用だとコンポーネントをグローバルに紐付ける
    • webpackerをサポートしたので、webpackerを利用していればグローバルではなくなる
  • CSRFトークンをpropで渡す必要がある
  • デフォルトはsprockets利用
    • レールに乗ったままいける
    • 確か内部でreact.jsを持っている(バージョンがちょっと古い)
      • reactのaddonsの利用をサポートしているから?
    • すぐにnpm使いたくなる
      • 今はwebpackerと組み合わせる方法がある
      • 他はbrowserify-rails使う方法かRailsAssets.orgかな?

react_on_rails

https://github.com/shakacode/react_on_rails

  • execjs依存
  • Rails疎結合でReactを利用できる
    • Rails側で使いやすいようにヘルパーやnpmのライブラリを提供している
  • CSRFはnpmでライブラリが用意されている
    • ReactOnRailsで取得可能
  • 非SPAだと重厚すぎないか?
csrfToken = ReactOnRails.authenticityToken();

// compose Rails specific request header as following { X-CSRF-Token: csrfToken, X-Requested-With: XMLHttpRequest }
header = ReactOnRails.authenticityHeaders(otherHeader);
  • 利用例はr7kamuraさんのamakanが秀逸

http://r7kamura.hatenablog.com/entry/2016/10/10/173610

その他

ExecJSとは

Rubyからjavascriptを実行できるようにするためのもの。

javascriptランタイムを抽象化して同じインターフェースで利用できるようにする。

ランタイム

  • therubyracer
    • Gemfileでデフォルトで入っていたやつ
    • メモリ使用量が多いのが難点
    • インストールも苦労するのだが
    • 最近はmini_racer推奨
  • Node.js
    • いわずとしれたサーバサイドでも使えるjavascript
  • mini_racer
    • therubyracerよりも高速、安定、省メモリ
    • therubyracerが抱えていた古いV8エンジンの問題も解決

Railsのwebpackerでbin/webpack-dev-serverをした時にinvalid host headerになってしまう

Railsのwebpackerでbin/webpack-dev-serverをしてブラウザからアクセスするとinvalid host headerとJSのエラーになってしまった。

(Virtualboxに開発環境を作ってホストOSのブラウザからアクセスしている)


とりあえず、下記の設定を入れてエラーを回避しているが、どうやるのが正しいのだろう。

[config/webpack/development.js]

module.exports = merge(sharedConfig, {
    ・・・

  devServer: {
    disableHostCheck: true,
    ・・・
  }

HerokuのRailsでnpm installをできるようにする

1. 下記の手順に従ってrubyとnodejsのビルドパックを追加する

devcenter.heroku.com

$ heroku buildpacks:add --index 1 heroku/nodejs
Buildpack added. Next release on アプリ名 will use:
  1. heroku/nodejs
  2. heroku/ruby
Run git push heroku master to create a new release using these buildpacks.

2. assets:precompileの前にnpm installを行うRakeタスクを作成する

[lib/tasks/before_precompile.rake]

task :npm_install do
  sh "npm install"
end

Rake::Task["assets:precompile"].enhance(%i(npm_install))

手順2. は要らなさそう。Herokuがyarnをサポートしているようなのでyarn.lockファイルがあるとyarn installが自動で走るみたい。

devcenter.heroku.com

Herokuのタイムゾーンを日本にする

Herokuのタイムゾーンを日本時間に設定する - アインシュタインの電話番号を参照

コマンド

heroku config:set TZ=Asia/Tokyo