Rails4 scopeでActiveRecordを簡潔に
ActiveRecordを簡潔に書くことができるscopeのメモ。
scopeの定義
class User < ActiveRecord::Base scope :created_before, ->(datetime) { where("created_at < ?", datetime) } end
scopeはクラスメソッドのようにも、インスタンスメソッドのようにも使える。
# クラスメソッドのように使う User.created_before(DateTime.now) # インスタンスメソッドのように使う user.created_before(DateTime.now)
scopeは複数組み合わせることができる
class User < ActiveRecord::Base scope :created_before, ->(datetime) { where("created_at < ?", datetime) } scope :order_id, -> { order(:id) } end
使い方
# クラスメソッドのように使う User.created_before(DateTime.now).order_id # インスタンスメソッドのように使う user.created_before(DateTime.now).order_id
Rails4 chart.jsのレーダーチャートをwicked_pdfでPDF出力 ※windows未対応
chart.jsで描画したレーダーチャートをwicked_pdfを使って、PDF出力する手順のメモ。
chart.jsで描画したレーダーチャートをwicked_pdfを使って、PDF出力しようとしたらうまくいかなかった。
wickee_pdf推奨のgem「wkhtmltopdf-binary」が更新されていないのが主な原因だった。
新たに「wkhtmltopdf-binary-11」というgemを見つけたので、これに差し替えた。
まず、Gemfileに下記を追加する。
gem 'wkhtmltopdf-binary-11' gem 'wicked_pdf'
コマンドプロンプトでbundle installを実行する。
bundle insatall --path vendor\bundle
config/initializers/wicked_pdf.rbファイルを作成し、wkhtmltopdfのパスを記載する。
WickedPdf.config = { :exe_path => "#{Gem.loaded_specs['wkhtmltopdf-binary-11'].full_gem_path}/bin/wkhtmltopdf" }
グラフの表示で、アニメーションをオフにする必要がある。
<!--レーダーチャートを描画する Canvas--> <canvas id="canvas" width="300px" height="300px"> </canvas> <%= javascript_include_tag "Chart" %> <script> $(function() { // レーダーチャートで表示するデータを用意 var radarChartData = { labels: ["スタミナ", "スピード", "テクニック", "パワー", "メンタル"], datasets: [ { fillColor: "rgba(151,187,205,0.5)", // 線で囲まれた部分の色 strokeColor: "rgba(151,187,205,1)", // 線の色 pointColor: "rgba(151,187,205,1)", // 点の色 pointStrokeColor: "#fff", // 点を囲む線の色 data: [7,8,10,6,10] } ] }; // Canvas にレーダーチャートを描画 var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var chart = new Chart(context); var rader = chart.Radar(radarChartData, { scaleShowLabels: true, // 目盛を表示 pointLabelFontSize: 10, // ラベルを表示 animation: false // アニメーションをオフに }); }); </script>
※注意
windows環境では動作しない。
参考:
Rails4 wicked_pdfでPDF出力 ※windows未対応 - ayaketanのプログラミング勉強日記
Rails4 Chart.jsでレーダーチャートを表示する - ayaketanのプログラミング勉強日記
wkhtmltopdf-binary-11 | RubyGems.org | your community gem host
Rails4 form_tagでactionとmethodを指定する
form_tagでactionとmethodを指定したかった。
ルーティングは下記のように設定してあった。
resource :test, only: [:edit, :update]
edit内で、form_tagを使用していたが、初期値では、methodがpostになってしまったため、自分でmethodにpatchを指定する必要があった。
まず、下記のように記載したが、うまくいかなかった。
<%= form_tag({action: 'update', method: 'patch'}) do %>
HTMLのソースを表示すると、下記のようにmethodがactionの一部になっていた。
<form accept-charset="UTF-8" action="/test?method=patch" method="post">
下記のようにハッシュを分けるとうまくいった。
<%= form_tag({action: 'update'}, {method: 'patch'}) do %>
HTMLのソースを表示すると、actionもmethodも正常に設定されていることが確認できた。
<form accept-charset="UTF-8" action="/test" method="post"> <input name="_method" type="hidden" value="patch" />
Rails4 複数のチェックボックスの入力結果を配列で取得すると、不要な"0"が含まれる
ユーザーをグループ分けするときに、そのグループに所属するユーザーをチェックボックスで選択したい。
複数のチェックボックスの入力結果を処理するときに、不要な"0"が取得できてしまったので、メモ。
まずは、ビューでチェックボックスを実装
<% @users.each do |user| %> <%= f.check_box :user_id, {:name => "grouping[user_id][]"}, user.id %> <%= f.label :user_id, user.name, :value => user.id %> <br> <% end %>
すると、HTMLは次のようになった
<input name="grouping[user_id][]" type="hidden" value="0" /> <input id="grouping_user_id" name="grouping[user_id][]" type="checkbox" value="1" /> <label for="grouping_user_id_1">ユーザー1</label> <br> <input name="grouping[user_id][]" type="hidden" value="0" /> <input id="grouping_user_id" name="grouping[user_id][]" type="checkbox" value="2" /> <label for="grouping_user_id_2">ユーザー2</label> <br> <input name="grouping[user_id][]" type="hidden" value="0" /> <input id="grouping_user_id" name="grouping[user_id][]" type="checkbox" value="3" /> <label for="grouping_user_id_3">ユーザー3</label> <br>
意図しない
<input name="grouping[user_id][]" type="hidden" value="0" />
が追加されている。
チェックボックスでユーザー1を選択してsubmitすると、params[:grouping][:user_id]には["0","1","0","0"]と、不要な"0"が入っていた。
この"0"は未選択時のためにあるようですが、あると処理がしにくいので、コントローラで削除する必要があります。
コントローラで"0"を削除
params[:grouping][:user_id].delete("0")
すると、params[:grouping][:user_id]は、["1"]になった。
ついでに、文字列の配列を数値の配列に変換し、処理しやすくした。
user_ids = params[:grouping][:user_id].map{|s|s.to_i}
参考:
プログラマの覚書: Rails チェックボックスの配列化(修正)
Ruby on Railsで絞り込み用に複数のチェックボックスを作成する方法 | もっとクールにプログラミング
文字列の前後の空白を削除する
stripで文字列の前後の空白を削除しようとしたら、全角スペースが削除されなかった。
そこで、メソッドを自作することにした。
class String # 文字列前後の全角・半角スペースを削除 def strip_with_full_size_space! self.gsub!(/^[ \s]*(.*?)[ \s]*$/, '\1') end # 文字列前後の全角・半角スペースを削除した文字列を返す def strip_with_full_size_space clone.strip_with_full_size_space! end end
これで、全角・半角スペースにはもちろん、タブにも対応できた。
参考:
Ruby【全角空白も除去】できるstrip!()ありますか? s = " 全.. - 人力検索はてな
rubyで行頭や行末の全角スペースを除去する方法 - memo.yomukaku.net
正規表現の構文
Rails4 アップロードしたファイルのテスト
前回、csvファイルをアップロードして読み込む方法を調べた。
Rails4 csvファイルをアップロードして読み込む - ayaketanのプログラミング勉強日記
そのテストをおこなうため、アップロードしたファイルのテスト方法を調べた。
fixture_file_uploadを使うと、\spec\fixturesに入っているファイルのアップロードがおこなえる。
テスト用にアップロードするファイルを準備
\spec\fixtures\filesにテスト用ファイルtest_user.csvファイルを入れる。
fixture_file_uploadを使用可能にする
\spec\models\user_spec.rbの先頭でinclude
include ActionDispatch::TestProcess
ファイルをアップロードして、テストをおこなう
\spec\models\user_spec.rbにテストを書く。
it "CSVファイルを読み込んで、ハッシュの配列に変換する" do csv_file = fixture_file_upload('files/test_user.csv', 'text/csv') csv_data = User.load_csv(csv_file) # ここにテストを書く end
参考:
【ruby】Railsでファイルアップロードをテストする - tanihiro.log
test a file upload using rspec - rails - Stack Overflow
Rails4 csvファイルをアップロードして読み込む
ユーザーをCSVファイルから登録したかった。
csvファイルをアップロードして読み込む方法をメモする。
ルーティングの設定
アップロードするCSVファイルの指定画面と、CSVファイルの読み込み処理のルーティングを設定する。
config\routes.rbに下記のように記載する。
resources :users do collection do get 'import_csv_new' post 'import_csv' end end
ビューの作成
CSVファイルの指定画面を作成する。
app\viewsにimport_csv_new.html.erbファイルを作成し、下記のように記載する。
※form_tagでは、multipartを別ハッシュにすること。
<h1>社員登録(CSVファイル)</h1> <%= form_tag({controller: "users", action: "import_csv", method: "post"}, {multipart: true}) do %> <div class="field"> <%= label_tag "CSVファイルを選択" %><br> <%= file_field_tag :csv_file %> </div> <div class="actions"> <%= submit_tag "CSVファイルを読み込む"%> </div> <% end %> <%= link_to '社員一覧に戻る', users_path %>
コントローラの作成
app\controllers\users_controller.rbに下記を追記する。
def import_csv_new end def import_csv respond_to do |format| if User.impotr_csv(params[:csv_file]) format.html { redirect_to users_path } format.json { head :no_content } else format.html { redirect_to users_path, :notice => "CSVファイルの読み込みに失敗しました。" } format.json { head :no_content } end end end
モデルのメソッドの作成
app\models\user.rbにメソッドを作成する。
まず、ファイルの先頭でライブラリを2つ読み込む
# coding: utf-8 require 'csv' # csv操作を可能にするライブラリ require 'kconv' # 文字コード操作をおこなうライブラリ class User < ActiveRecord::Base
CSVファイルを読み込み、ユーザーを登録する関数を作成する。
※実際はデータチェックなどが必要
# CSVファイルを読み込み、ユーザーを登録する def import_csv(csv_file) # csvファイルを受け取って文字列にする csv_text = csv_file.read data = [] #文字列をUTF-8に変換 CSV.parse(Kconv.toutf8(csv_text)) do |row| user = User.new user.name = row[0] #csvの1列目を格納 user.kana = row[1] #csvの2列目を格納 user.address = row[2] #csvの3列目を格納 user.tel = row[3] #csvの4列目を格納 user.save end end
参考:
Ruby on Rails 3.2: CSVをアップロードしてActiveRecordにつっこむ | DYO.JP ver.2
【前編】SHIFT-JISのCSVをUTF-8でRailsにインポート (Rails 3.2.13) | heathrow.lab
【後編】SHIFT-JISのCSVをUTF-8でRailsにインポート (Rails 3.2.13) ~ActiveModelの活用 | heathrow.lab
Railsでuploadされたfile(txt等)の内容を読み込む - 初心者エンジニアのメモ帳
ファイルをアップロードしてみよう(file_field) Ruby on Rails Pro