the industrial

都内で働くITエンジニアの日記

railsのransackでハマった話

ソースはすべて雰囲気(動作確認してないっす)。

今日ハマってた所。

例えば、 parents TBLchildes TBL があったとして、

CREATE TABLE `parents` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=565 DEFAULT CHARSET=utf8;

CREATE TABLE `childes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `fk_rails_36a4cd8620` FOREIGN KEY (`client_office_id`) REFERENCES `client_offices` (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=utf8;

childes TBL の要素で作成したドロップダウンで選択したidを保持する、 parents TBL のみ取得したいというケース。

modelにこういった形で定義しておけば

class Parents < ActiveRecord
  has_many :childes
  
  scope :has_childe_id, -> (childe_id) {
    eager_load(:childes).where('childes.id = ?', childe_id)
  }

  # for ransack scope
  def self.ransackable_scopes(auth_object=nil)
    %i(has_childe_id)
  end
end

(画面側)

<% f.select :has_childe_id, Childes.all.map {|c| [c.name, c.id]}, { include_blank: true }, { class: 'form-control' } %>

SQLがこんなふうに、うまい具合に発行されることはわかった。

SELECT
        `parents`.`id` AS t0_r0
        ,`parents`.`name` AS t0_r1
        ,`childes`.`id` AS t2_r0
        ,`clients`.`name` AS t2_r1
    FROM
        `parents` LEFT OUTER JOIN `childes`
            ON `parents`.`id` = `childes`.`parent_id`
    WHERE
         (
            childess.id = '2'
        )

しかし、childsのidが'1'だった場合、何故かこんなエラーが・・・

wrong number of arguments (0 for 1)

原因は、ransackのメソッドが 1 という値を自動でboolean値と解釈してしまうんだとか?

github.com

なので、↑のページを参考に、コントローラーに

params[:q][:has_childe_id] = [params[:q][:has_childe_id]] if params[:q].present?

みたいなのを書いて、

{
  "utf8" => "✓",
  "q" => {
    "has_consultant_id" => "1"
  },
  "commit" => "検索",
  "controller" => "parents",
  "action" => "index"
}

ってくるパラメータを

{
    "utf8" => "✓",
    "q" => {
      "has_consultant_id" => [
        [0] "1"
      ]
    },
    "commit" => "検索",
    "controller" => "parents",
    "action" => "index"
}

といった形に整形・・・。

いやー、これ絶対間違ってるよなー・・・。

あれ、でもこれで治ってるのかな?

Config option for turning off custom scope argument sanitization by garettarrowood · Pull Request #742 · activerecord-hackery/ransack · GitHub