woshidan's loose leaf

ぼんやり勉強しています

Rails

Ransackで関連モデルの検索を行う

Ransackでは特定のモデルのカラムだけでなく、そのモデルと関連する他のモデルのカラムでも検索を行うことができる。 例えば、Userモデルに1対多で紐づくCommentモデルのcontents属性で検索したい場合 <%= search_form_for(@q, url: user_search_path) do |f…

RansackでRailsの検索を楽に作る

Railsで開発していると検索フォームを作成することがよくあると思います。 今日は、そのときよく使われるRansackについてまとめておこうと思います。 基本的な使い方 def index @q = User.ransack(params[:q]) @users = @q.result end のように特定のパラメ…

Rails6.1になってコントローラのテンプレート指定に拡張子をつけることが推奨されなくなった

Rails 6.1以上になってCSVなどをダウンロードさせるコントローラのアクションに def download render( csv: 'users_list', template: 'users/download.csv.ruby' ) end のように書いているとRSpecの実行時に DEPRECATION WARNING: Rendering actions with '.…

Enumerizeでenum値を扱う

Railsのモデルでenum値を扱うとき、enumerizeというgemを使うと便利です。 # Gemfile gem 'enumerize' class Task extend Enumerize enumerize :status, in: { pending: 0, todo: 1, done: 2 } end と書くと、 Task = Task.new(status: 'pending') #=> valid…

定数値を環境ごとに分岐したいだけならRails.env.xxx? やconfig/environments以下のファイルに値を書くより環境変数にくくり出した方がよさそう

Railsで開発していると if Rails.env.production? # production環境用の処理 elsif Rails.env.staging? # staging環境用の処理 else # それ以外の環境用の処理 end という風に環境ごとの処理を書いたり、config/environments以下のproduction.rbやstaging.rb…

少しだけ動作が速くなるコードの書き方3つ

レコードがあることを条件にしたいとき、findの代わりにexists?を使う if User.find_by(email: "...") # something.todo end のとき、findやfind_byではActiveRecordのインスタンスが生成されてしまう分遅いので、存在確認をしたいだけなら下記のようにexist…

Railsのuniquenessバリデーションについて

uniquenessバリデーションを使うと、その項目の中で一意であるようにバリデーションがかけられます。 class User validates :email, uniqueness: true end とすると、emailはUserの中で一意となるようにRails側でバリデーションをかける。 これを、Userが会…

Railsのルーティングの細かいところについて

最近細かく引っかかっていたので。 URLヘルパのnew, editの修飾子は前に付く xxxx_new_pathかnew_xxxx_pathかよく迷っていたけど、 new_xxxx_path, edit_xxxx_path のほうが正解。namespaceで # routes.rb namespace 'admin' do resources xxxxs end となっ…

ActiveRecordで関連しているモデルに対してメソッドを定義する

Userと1対多関連の関係にあるCommentというモデルがあるとする。 あるUserに関連したコメントに対して user.commentes.some_method のようにスコープやメソッドを定義したいという場合があって、その場合以下のように書ける。 class User < ApplicationRecor…

attributes_forでテスト用のハッシュを取得するときはFactoryに定義された属性しか取り出されない

下準備としてモデルのSchemeとFactoryの定義 # schema.rb ActiveRecord::Schema.define(version: 2020_11_23_064724) do create_table "users", force: :cascade do |t| t.string "name" t.integer "age" t.string "mail" t.datetime "created_at", precisio…

config/routes.rbのshallow: trueとは

仕事で見てよく分からなかったので調べてみた。 http://qiita.com/kuboon/items/96bbd227f9497ed81f38 resources :groups do resources :users end resources :users group_users GET /groups/:group_id/users(.:format) users#index POST /groups/:group_id…

テストのないコントローラをいじるときはナビゲーションテストだけでも書くと救われる

コントローラのテストがほとんどない状態からテストを書くの、結構苦しいなぁ、となって、 とりあえずコントローラに長々書いてある分はテストしやすいようにModelに括りだして分割してテストしたんですが、 そこで気が抜けて、インスタンス変数修正漏れアウ…

ActiveRecordでgroupingに計算値を使いたい、計算値を集計したい場合

.group(Arel.sql('DATE_FORMAT(updated_at, '%Y-%m-%d')')) とか .sum(Arel.sql("price * #{CONSUMPTION_TAX_RATE}")) のようにArel.sql()で包んでから放り込む。 と思っていたけど、包まなくても割といけたぞ。何故だ! Book.group('DATE_FORMAT(updated_at,…

FactoryGirlでfactory定義のブロックでデフォルトのアソシエーションを書くとその都度関連先のレコードが作成される

FactoryGirlでassociationを使うとき、 factory :item_one, class: Item do name 'first' association :user, factory: :user_one memo 'memo' category_id 1 end のようにassociationの部分の列を書くと、アソシエーションが含まれているfactoryを使ってレ…

ActiveRecordのmigrationまわり眺めてた

ActiveRecordでいくつかのメソッドでクエリを読もうと思っていたはずが、 なんか迷子になってしまいました。まさにぼんやり勉強しています、だ。 それでmigrationファイルの生成について、 rails g migration filename をしっかり書くと、templateの方で 属…

bootstrap-sassを使っているのに、bootstrapが使えない

もしかして、 /*= require bootstrap でなく、 @import "bootstrap-sprockets"; @import "bootstrap";

RailsのModelとControllerにどういうメソッドを書くのか

RailsのModelとControllerにどういうメソッドを書くのか分からなくてグルグルしていた。 好みやプロジェクトの雰囲気によると思うのだけれど、自分の実感として、 使い回さない判定 使い回さない検索 はControllerに書いてあることが多い気がする*1。 自分と…