Rails4 3階層のincludesの指定
N+1問題解決のため、includesの設定をしていた。
groupがuserを参照しており、userがdepartmentを参照しているとき、groupからdepartmentをincludesで指定するのにちょっと手間取った。
group → user → department
下記のように書いてもうまくいかなかった
# @groups = Group.order(:id) @groups = Group.order(:id). includes(:user, :department)
下記のように書いたらうまくいった
# @groups = Group.order(:id) @groups = Group.order(:id). includes({user: :department})
参考:
Ruby on Railsあれこれ/findメソッドの:includeオプションの書き方 - 笑猫酒家
N+1問題の対策のため、「Bullet」をインストール - ayaketanのプログラミング勉強日記
Rails4 where句をnotで否定する
私は今まで、点数がある点数以外のときというスコープを下記のように書いていました。
scope :score_is_not, ->(score) {where("score != ?", score)}
いまさらですが、Rails4では、where句をnotで否定できるようです。
scope :score_is_not, ->(score) {where.not(score: score)}
もちろん、通常のActiveRecordでもnotは使えます。
Test.where.not(score: 0) # Test.where("score != 0")
また、INでもnotは使えるようです。
Test.where.not(score: [0, 100]) # Test.where("score NOT IN (0, 100)")
参考:
#400 What's New in Rails 4 - RailsCasts
Ruby on Rails で NOT IN な SQL をかく。 - そんなこと覚えてない
Rails4 rspecとFactoryGirlを用いたdeviseでサインインした状態でのコントローラのテスト
サインインをdeviseを用いて実装している。
サインイン必須のコントローラのテストをおこなうときに、サインイン状態を作るのに少し手間取ったのでメモ。
spec\spec_helper.rbに下記のように記載
RSpec.configure do |config| … config.include Devise::TestHelpers, type: :controller # これを追加 end
spec\factories\user.rbに下記のように記載
FactoryGirl.define do factory :user do email "user@test.com" password "userpassword" password_confirmation "userpassword" end end
コントローラのテストでは、下記のようにサインインやサインアウトをおこなう
before do # ユーザー作成 @user = create(:user) # サインイン sign_in @user end after do # サインアウト sign_out @user end
参考:
plataformatec/devise · GitHub
Railsのユーザ認証deviseを用いた簡単かつ突っ込んだ実装 - ema25の日記
Rails4 simplecovでテストカバレッジを調べる
specでテストを書いていますが、すべてのテストがかけているか不安だったので、カバレッジを調べることにした。
simplecovというgemを使うといいようだ。
Gemfileに次のように追記し、bundle install
# カバレッジ gem "simplecov", require: false, group: :test
spec/spec_helperに下記を追記
# カバレッジを計測 require "simplecov" SimpleCov.start "rails"
あとは、いつも通りテストを実行すれば、coverage/index.htmlに結果が出力されます。
参考:
colszowka/simplecov · GitHub
Rails/Ruby - テストカバレッジを調べる simplecov - そういうことだったんですね
Rails4 flashのメッセージが2回表示される
flashに設定したメッセージが2回表示されて困ったのでメモ。
下記のようにflashにalertを設定し、newを再表示していた。
flash[:alert] = "登録に失敗しました。" render action: 'new'
登録画面で登録ボタンを押下すると、正常にメッセージが表示されたが、再度登録画面を表示すると、また同じメッセージが表示されてしまった。もう一度登録画面を表示すると、メッセージは表示されなかった。
正しくは、下記のように記載しなければいけなかったようだ。
flash.now[:alert] = "登録に失敗しました。" render action: 'new'
flash.now
現在のリクエストでのみ有効なメッセージを設定する。
現在のリクエストが終了した時点で、自動的にメッセージは削除される。
renderで表示する画面にメッセージを表示したい場合に用いる。
flash
次のリクエストまで有効なメッセージを設定する。
次のリクエストが終了した時点で、自動的にメッセージは削除される。
redirect_toした先の画面でメッセージを表示したい場合に用いる。
私はrenderでnewを再表示していたのに、flashを使っていたため、期待していた画面の1つ先の画面にまでメッセージが表示されていたようだ。
参考:
[Rails] flash.now[:notice]とflash[:notice]の違い - 拝啓、シーシュポス
Rails4 Chart.jsでレーダーチャートの背景色をなくす
レーダーチャートで3つのデータを比較したかった。
下記のように記載していたが、背景色があると、見にくいと感じました。
var radarChartData = { labels: <%= @labels.html_safe %>, datasets: [ { fillColor: "rgba(151,187,205,0.5)", // 線で囲まれた部分の色 strokeColor: "rgba(151,187,205,1)", // 線の色 pointColor: "rgba(151,187,205,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data1 %> }, { fillColor: "rgba(255,146,180,0.5)", // 線で囲まれた部分の色 strokeColor: "rgba(255,146,180,1)", // 線の色 pointColor: "rgba(255,146,180,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data2 %> }, { fillColor: "rgba(174,255,132,0.5)", // 線で囲まれた部分の色 strokeColor: "rgba(174,255,132,1)", // 線の色 pointColor: "rgba(174,255,132,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data3 %> } ] };
色が重なって、なんだか見にくい気がする。
fillColorの行を削除してみたが、うまくいかなかった。
そこで、背景色に白の透明を指定してみたらうまくいった。
var radarChartData = { labels: <%= @labels.html_safe %>, datasets: [ { fillColor: "rgba(255,255,255,0)", // 線で囲まれた部分の色 strokeColor: "rgba(151,187,205,1)", // 線の色 pointColor: "rgba(151,187,205,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data1%> }, { fillColor: "rgba(255,255,255,0)", // 線で囲まれた部分の色 strokeColor: "rgba(255,146,180,1)", // 線の色 pointColor: "rgba(255,146,180,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data2 %> }, { fillColor: "rgba(255,255,255,0)", // 線で囲まれた部分の色 strokeColor: "rgba(174,255,132,1)", // 線の色 pointColor: "rgba(174,255,132,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: <%= @data3 %> } ] };
背景色がなくなり、線だけのレーダーチャートになった。
印刷で改ページを指定する(PDF出力対応)
PDF出力時の改ページを指定したかった。
印刷で改ページを指定するのと同じ方法で対処できたのでメモ。
CSSで印刷時の改ページの位置を指定できるようだ。
page-break-before | 要素の直前の改ページを制御 |
page-break-after | 要素の直後の改ページを制御 |
制御方法は次の3種類
auto | 制御しない (初期値) |
always | 直後で改ページさせる |
avoid | 直後の改ページを禁止 |
私は、要素の直前で改ページを指定したかったので、CSSに下記のように記載した。
.new_page { page-break-before: always; }
item毎に改ページをしたかったので、itemのタイトルに改ページを指定した。
<h2 class="new_page"><%= item.title %></h2>
heroku上でPDF出力した際に、正しく改ページがされることを確認した。
参考:
スタイルシート[CSS]/ページ全般/印刷時の改ページ部分を指定する - TAG index Webサイト
Rails4 wicked_pdfでPDF出力 ※windows未対応 - ayaketanのプログラミング勉強日記