Adequate Recordでキャッシュされないケースヘ(^o^)ノ
第65回 Ruby関西 勉強会に参加したよヘ(^o^)ノのつづき
スライドに、Adequate Recordでキャッシュされないケースを書いたけど、 ざっくりしすぎなのでまとめてみる( ˘ω˘)
find_byを例にactiverecordのコードを読みながら確認していく
コードはこんな感じ(コメントの*1
とかは説明しやすいのでつけてるだけ)
# activerecord/lib/active_record/core.rb def find_by(*args) # :nodoc: # *1 return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any? # *2 return super if default_scopes.any? hash = args.first # *3 return super if hash.values.any? { |v| v.nil? || Array === v || Hash === v } # We can't cache Post.find_by(author: david) ...yet # *4 return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) } ... end
*1
で判定していること
current_scopeがある
current_scope
でスコープがないことを確認してる
引数がHash以外
!(Hash === args.first)
でチェックしてる
こんなのはキャッシュしてくれない
Post.find_by('created_at < ?', 1.weeks.ago)
composed_ofが設定されている
reflect_on_all_aggregations.any?
でチェックしてる
設定されているだけでキャッシュしてくれない
*2
で判定してること
default_scopeが設定されている
設定されているだけでキャッシュしてくれない
*3
で判定していること
引数のハッシュ値(Value)がnil
, Array
,Hash
こんなのはキャッシュしない
Post.find_by(title: nil) Post.find_by(title: ['ruby', 'rails']) # Hashがくるケースが思い浮かばない...
*4
で判定していること
Hashのキーにモデルのカラム以外が指定されている
以上の条件に当てはまる場合に、super
すなわち本家のfind_by
をよんでます
なので、単一テーブル継承(STI)やPolymorphicは、設定されているだけではキャッシュの対象外とはなりません
ここがややこしそうだ。。。
間違えてたら教えてくださいねー
Happy Hacking٩( ‘ω’ )و
神戸.rb Meetup #13に参加したよヘ(^o^)ノ
神戸.rb Meetup #13に参加しましたー
毎回思うがホント勉強になる
僕の思いもみんなに伝えられたし良かった
今日はActiveSupport::StringInquirerについて調べた
結構こんなの書いちゃいがちですよね?
if Rails.env == 'production' ... end
それが、こう書ける
if Rails.env.production? ... end
これを使ってこんなの実装してみた
priority_typeってフィールドがあって、'low'や'high'なんかの文字列がセットされてるとする
class Task < ActiveRecord::Base def priority priority_type.inquiry end end
lowかどうかチェックしてみる
task.priority_type #=> "low" task.priority.low? #=> true task.priority.middle? #=> false
==で判定するよりグッと意図が伝わりやすくなってると思う(多分...
Happy Hacking٩( ‘ω’ )و
RubyのHashで要素数を取得するヘ(^o^)ノ
Hashで要素の数を取得してみる
Hash#lengthとHash#size
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.length #=> 3 favorites_language.size #=> 3
Enumerable#count
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.count #=> 3
では、Valueが'Ruby'である要素の数を取得してみる
Hash#lengthとHash#size
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.select{|k, v| v == 'Ruby'}.size #=> 2
Enumerable#count{|obj| ...}
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.count{|key, v| v == 'Ruby'} #=> 2
そう!countにはブロックを渡せるのだー(今までマジで知らんかった...
もう少しおしゃれにしてみよう
Enumerable#count(item)
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.values.count('Ruby') #=> 2
まだまだ知らんこといっぱいですわー
がんばろっと
Happy Hacking٩( ‘ω’ )و
第65回 Ruby関西 勉強会に参加したよヘ(^o^)ノ
第65回 Ruby関西 勉強会に参加し、発表してきました。
発表内容はRails4.2の新機能について。
4.2がリリースされてから2ヶ月が経ちますが、ActiveJob中心に紹介させてもらいました。
発表中にデモする時があると思います
スライド見ながらタイプするの大変ですよねー( ̄▽ ̄;)
そんな時はtmuxですよ!
- tmuxを起動
- 新しいターミナルから、起動済みtmuxへアクセス
$ tmux attach -t 0
- 普通に操作する
これで発表中のデモも楽ちんですねーヘ(^o^)ノ
Happy Hacking٩( ‘ω’ )و
みなさんの発表内容
Ruby 2.0 以降の変更をふりかえる
RubyでBCCWJを弄ぶ
@pico1aさん
Wakayama.rbボードの紹介
Rubyコミュニティx企業
Medaka.rb活動概要
Gemをコードリーディングしてみよう!
@taiyopさん
Railsの見える化 開発(API編)
@ogomさん
Treasure DataでのRubyの利用
追記
- 2014/02/27 @takamiya_amsさんのスライド追加
Gitのコンフリクト時にmergetoolで確認してマージするヘ(^o^)ノ
Gitでコンフリクトしたときに、GUIやIDEだと差分が確認しやすいみたい。
でも、僕はVimなの...
そこでmergetoolですよ!
実際にやってみよう。
# hello.rb class Hello def say "Hello" end end
コミットして、ブランチを切ります。
$ git init $ git add . $ git commit -m 'first commit' $ git checkout -b add_name
修正してみます。
# hello.rb class Hello def say(name) "Hello #{name}" end end
コミットして、masterブランチへ
$ git add . $ git commit -m 'add name' $ git checkout master
わざとコンフリクトさせてみましょう。
マージする前に、masterブランチのファイルを修正します。
# hello.rb class Hello def say "Hello!" end end
コミットして、マージします。
$ git add . $ git commit -m 'add exclamation mark' $ git merge add_name
コンフリクトしました!
Auto-merging hello.rb CONFLICT (content): Merge conflict in hello.rb Automatic merge failed; fix conflicts and then commit the result.
コマンドを実行します。
$ git mergetool
- 左はマージする前の状態
- 右はマージしたいところ
- 中央は右のマージしたいところが作られる前の状態
- 下はマージして保存するファイル
どうですか?
今のmasterブランチの状態と、マージ前の状態とマージしようとしているファイルの状態が
わかりやすいですよね?
masterブランチには'!'が、add_nameブランチにはnameが追加されています。
ファイルを編集して、保存します。
# hello.rb class Hello def say(name) "Hello #{name}!" end end
コンフリクトしたときのファイルはhello.rb.orig
で保存されています。
必要なければ削除して、コミットしましょう。
$ git commit -m 'merge add_name'
これで、コンフリクトのマージ作業が安全に行えそうですね。
Happy Hacking٩( ‘ω’ )و
d(゚Д゚ )☆スペシャルサンクス☆( ゚Д゚)b
神戸.rb Meetup #12に参加したよーヘ(^o^)ノ
神戸.rb Meetup #12に参加しました。
僕はKonachaについて調べてました。
会社でRailsのJavaScriptをええー感じにテストしたい!ってことなので
# Gemfile group :test, :development do gem 'konacha' gem 'selenium-webdriverd' end
デフォルトのdriverはselenium
です。
実際にテストを書いてみる
# app/assets/javascripts/hello.js.coffee class @Hello @say_hello: (name) -> "Hello #{name}!"
# rspec/javascripts/hello_spec.js.coffee #= require hello describe 'Hello#say_hello', -> it "returns 'Hello murajun1978!'", -> expect(Hello.say_hello('murajun1978')).to.eql("Hello murajun1978!")
テストを実行する
$ bundle exec rake konacha:run . Finished in 0.00 seconds 1 examples, 0 failed, 0 pending
テスト通ったねー
んじゃ、headlessでテストしてみる
# Gemfile gem 'poltergeist' # gem 'selenium-webdriver'
# config/initializers/konacha.rb Konacha.configure do |config| require 'capybara/poltergeist' config.driver = :poltergeist end if defined?(Konacha)
headlessでテストできたねーヘ(^o^)ノ
Happy Hacking٩( ‘ω’ )و
追記
- 2015/02/23
- hello_spec.js.coffeeでrequireしていなかったので追記
- config.driverの指定が間違ってたので修正
神戸.rb Meetup #11 に参加したよヘ(^o^)ノ
Kobe.rbに参加してきたよヘ(^o^)ノ
今日のおやつ!! photo by @spring_aki
おいしかった♪
今日、僕が調べてたのはActiveDecorator + Capybara + RSpecです。
ActiveDecoratorでhelperを良く使いますよねー
例えばこんなの...
def full_name content_tag :td do "#{first_name} #{last_name}" end end
Decoratorが自動生成するRSpecはこちら
describe UserDecorator let(:user) { User.new.extend UserDecorator } subject { user } it { should be_a User } [...] end
毎回extendするのもアレなので、ActiveDecorator::RSpecを使います
# Gemfile gem 'active_decorator-rspec' # spec/decorator/user_decorator_spec.rb describe UserDecorator # FactoryGirlでテストデータ作成 let(:user) { build(:user) } subject { decorate user } it { should be_a User } [...] end
いい感じですねー
キモのfull_nameメソッドをCapybaraでテストしてみましょう
describe UserDecorator [..] it 'has a tr tag and full_name' do expect(subject.name).to have_content(:td, "#{user.first_name} #{user.last_name}") end end
実行すると怒られます。。。
undefined method 'content_tag' for ...
type: :heler
or type: :view
を指定すればhelperメソッドが認識されますが、
こんどはCapybaraにおこられます( ̄▽ ̄;)
have_contentはCapybara::RSpecMatchersで定義されてるのでincludeしてみます
describe UserDecorator include Capybara::RSpecMatchers let(:user) { build(:user) } subject { decorate user } it { should be_a User } it 'has a tr tag' do expect(subject.name).to have_content(:td) end end
これでテストを実行すればパスしますが、毎回includeはアレなのでrails_helperに追記
# spec/rails_helper.rb RSpec.configure do |config| config.include Capybara::RSpecMatchers, type: :decorator end
describe UserDecorator let(:user) { build(:user) } subject { decorate user } it { should be_a User } it 'has a tr tag', type: :decorator do expect(subject.name).to have_content(:td, "#{user.first_name} #{user.last_name}") end end
これでCapybaraを使ってテストできますねー
Happy Hacking٩( ‘ω’ )و