yposiのブログ

Web開発日記

キャッシュを親子に持たせるのは危険。子が死んでも親は残り続ける。

Rails.cacheの中でRails.cacheをするのは危険。 親子関係と呼ぶが正しい表現なのか?

子が死んでも親は残り続ける。

そんな悲しい話ある? プログラミングの話でもあれば悲しい話だと思った今日この頃。

なので子と親に差分があって、 更新系のあるデータを扱う場合でもそうでない場合でもやるな。 絶対やるなという話。

コンソール上で適当にやった

def caching_test(id)
  Rails.cache.fetch("user-caching-#{id}", expires_in: 1.day) do 
    lost_caching(id)
  end
end

def lost_caching(id)
  Rails.cache.fetch("user-child-caching-#{id}", expires_in: 60.seconds) do 
    User.find(id)
  end
end

user = caching_test(1)
=> #<User id: 1, ...>

Rails.cache.fetch("user-caching-1")
=> #<User id: 1, ...>

Rails.cache.fetch("user-child-caching-1")
=> #<User id: 1, ...>

1分たった後に

Rails.cache.fetch("user-child-caching-1")
=> nil

消えた。よし!

Rails.cache.fetch("user-caching-1")
=> #<User id: 1, ...>

いた。悲しい。

ちなみに更新系は値が変わらないで生き続けるので要注意。

あんまりRails.cache周りのコマンドを知らない人は参考になるサイト。
僕もあれって一瞬なったので、参考にさせてもらったサイト載せさせていただきます。

morizyun.github.io

sorceryのchange_password!の仕様が変わっているので注意

sorcery
sorcery

本番環境でパスワード変更ができなくなりました。辛い。

バージョン0.14の対応でsorceryのchange_password!の仕様が変わっておりました。

    # Clears token and tries to update the new password for the user.
    def change_password(new_password, raise_on_failure: false)
      clear_reset_password_token
      send(:"#{sorcery_config.password_attribute_name}=", new_password)
      sorcery_adapter.save raise_on_failure: raise_on_failure
    end

    def change_password!(new_password)
      change_password(new_password, raise_on_failure: true)
    end

github.com

世の中のブログで紹介されているsorceryの実装方法が上記変更を取り込んだ実装になっていないため更新時に例外が発生してします。

    if @user.change_password!(params[:user][:password])
      redirect_to(root_path, :notice => 'Password was successfully updated.')
    else
      render :action => "edit"
    end

サービス提供されている方はコードを見直すことをおすすめします。 あるいは、私の修正方法を取り込むことで改善できます。

修正前:

@user.change_password!(params[:user][:password])

修正後:

@user.change_password(params[:user][:password])

これでバージョン0.14より前の挙動と同じにすることができます。 例外を発生させなくするだけですが。。。

反省。。。

specがこの辺を拾える様になっていれば問題を起こすことなくgemのバージョンアップができたのですがそうなっていなかったので本番に影響を出してしまいました。 自戒の意を込めて「ちゃんとテストを書きましょう」と言いたいです。

Docker + Rails6環境でコード即時反映されない件

Rails 6 + Dockerを用いて今サービス開発を行っている。 webpackerを使っていて、./bin/webpacker-dev-serverで起動していたらコードが即時ブラウザに反映すると思っていたが更新されない。 そういう人いるんじゃないかな?それまで毎回コンテナーを再起動してました。面倒になったので対応しました。

なんでそういう挙動をするかはわかっていないが対応方法はわかったので記載する。

ファイル: config/environments/development.rb

修正前:

  # Use an evented file watcher to asynchronously detect changes in source code,
  # routes, locales, etc. This feature depends on the listen gem.
  config.file_watcher = ActiveSupport::EventedFileUpdateChecker

修正後:

  # Use an evented file watcher to asynchronously detect changes in source code,
  # routes, locales, etc. This feature depends on the listen gem.
  config.file_watcher = ActiveSupport::FileUpdateChecker

ひとまずこれで少し開発が進めれる様になったとさ。

fudo3をバージョンアップ

ここ2週間くらいお仕事がバタバタしていてgemの開発が進まなかったけどカフェに行けたので今少し改善しました。

github.com

修正内容は、

  • 坪単価の計算を追加
  • 平米単価の計算を追加

これだけだけど不動産システムを作っていた時にこういうメソッドがいた気がするので追加しました。

他にv0.1.0で追加したメソッドのちょっとした修正をしました。
動作に影響ないところで。

fudo3は「不動産のサービス内でよく使われる計算をまとめたgem」にしたいので是非フィードバックください。

頑張って機能開発・改善していきたいと思います。
よろしくお願いします。

gemの名前をつける時は「-」はつけないほうがいい

fudo3を作ったときのメモになりますが、 当初、fudo3はfudo-3という名前でした。
ハイフンをつけたことでディレクトリが階層化されクラスが「Fudo::3」という気持ち悪いクラスになりました。

gemの開発コマンド

$ bundle gem fudo-3 -t

としたところ、
当然ファイルが自動生成されました。
ですが、ディレクトリが階層化されちゃいました。

f:id:yposi2:20200825211935p:plain

ちょっと調べたところ「-」をつけることでディレクトが階層化になるそうです。

階層化したいケースはあまりないと思うので
ちょっとしたことですが「-」はつけない方がいいと思います。

gemビギナーなのでこれがきれいじゃないとは言い切れませんが。。。

ひとまず、「fudo3」が無事にリリースできたので記事を書いてみました。

RubyGems

ソースコード

RubyMineの.idea/の対処法

RubyMineお使いですか?

www.jetbrains.com

プロジェクトで自分だけが使用しているケースってあると思うんですよね。
そういうときに.gitignoreに追加されておらずうっかり.idea/をstageして焦ったみたいな経験はございませんか?

私がやっているやり方を共有したいと思います。
自分の環境下の全プロジェクトで任意のファイルを 個人的に バージョン管理対象外にするやり方になります。

設定ファイルを作ります。

$ touch ~/.gitignore_global

.gitignore_globalを編集します。

# RubyMine
.idea/
.idea/**/workspace.xml
.idea/**/tasks.xml

設定を適応します。

$ git config --global core.excludesfile '~/.gitignore_global'

[core]部分に追加されます。

$ cat ~/.gitconfig
[user]
    name = 名前
    email = メールアドレス
[core]
    excludesfile = ~/.gitignore_global

保存すると、以後.idea/のファイルは差分として出てこなくなります。

今更感もありますが、 ちょっとしたチップスでした。

RailsとJSの定義でなんだっけ?となったもの

RailsとJSの定義でなんだっけ?となったものについて簡単に調べました。

$(function () {
  // 処理
}

$.fn.hoge = function () {
  // 処理
}

function fuga() {
  // 処理
}

これらが同一ファイル内に記述されていて、それぞれの定義の違いがよくわからなかったので手元のメモを公開します。 正確には②がわかっていなかっただけなんだけど😅

①はページが読み込み完了し、DOMの構築が完了した時点でfunction()内が実行されます。
①はこの様にも書くことができます。

$(document).ready(function() {
  // 処理
});
jQuery(function(){ 
  // 処理
}

つまり、これでも書けることになる。

jQuery(document).ready(function(){
  // 処理
});

②は標準のjQueryオブジェクト$.fnに対してインスタンスメソッドを拡張しています。
つまり、これでも書けることになる。

jQuery.fn.hoge = function () {
  // 処理
}

Rails環境内でこの書き方を定義する場合、jQueryの拡張にあたるのでどこからでも呼べる様になる。
同一ファイル内で呼ぶメソッドをこの定義にする必要はない気がしてきた。
むしろ、メソッド名を奇跡的にもかぶらせたら挙動が変わってしまう可能性もあるなと思いました。

③はメソッドの定義ですね。

古いRailsのバージョンで動く、jsファイルに拡張に拡張を重ねた感じなんだろうけど②である必要はないのかな😅

Effective JavaScript

Effective JavaScript

  • 作者:David Herman
  • 発売日: 2013/02/19
  • メディア: 大型本