質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.60%

【Ruby on Rails】コントローラとルーティングに追加してるが、NoMethodError になる

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,098

pecchan

score 351

Win8.1 Rails 5.0.1 Ruby 2.3.3p222

表題の通りです。

コントローラにアクションを追加、
ルーティングにも追加してるんですが、
アクションを呼ぶとNoMethodErrorが表示されます。

何故でしょうか??

宜しくお願い致します。

●ルーティング

Rails.application.routes.draw do
  root 'products#index'

  resources :products, only: [:index] do
    collection do
       get :search
    end
  end

end

●コントローラ

class ProductsController < ApplicationController


  def index
     @product = Search::Product.new
  end

  def search
    @product = Search::Product.new(search_params)
    @products = @product
      .matches
      .order(availability: :desc, code: :asc)
      .decorate
  end


  def show
  end

  def new
    @product = Product.new
  end

  def edit
  end

  private


  # 検索フォームから受け取ったパラメータ
  def search_params
    params
      .require(:search_product)
      .permit(Search::Product::ATTRIBUTES)
  end


end

●呼出し側ビュー

<% content_for(:title) do %>
  商品検索
<% end %>

<%= form_for(@product, url: search_products_path, html: { method: :get, class: 'form-horizontal', role: 'form' }) do |f| %>
  <%= render 'search_form', f: f %>
<% end %>

【エラー画像追加】
イメージ説明

【rake routes 画像追加】
イメージ説明

【モデル追加】
app\models\search\base.rb

class Search::Base
  include ActiveModel::Model
  include ActiveModel::Validations::Callbacks

  def contains(arel_attribute, value)
    arel_attribute.matches("%#{escape_like(value)}%")
  end

  def escape_like(string)
    string.gsub(/[\\%_]/) { |m| "\\#{m}" }
  end

  def value_to_boolean(value)
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
  end
end

app\models\search\Product.rb

class Search::Product < Search::Base
  ATTRIBUTES = %i(
    code
    name name_kana
    price_from price_to
    purchase_cost_from purchase_cost_to
    availability
  )
  attr_accessor(*ATTRIBUTES)

  def matches
    t = ::Product.arel_table
    results = ::Product.all
    results = results.where(contains(t[:code], code)) if code.present?
    results = results.where(contains(t[:name], name)) if name.present?
    results = results.where(contains(t[:name_kana], name_kana)) if name_kana.present?
    results = results.where(t[:price].gteq(price_from)) if price_from.present?
    results = results.where(t[:price].lteq(price_to)) if price_to.present?
    if purchase_cost_from.present?
      results = results.where(t[:purchase_cost].gteq(purchase_cost_from))
    end
    if purchase_cost_to.present?
      results = results.where(t[:purchase_cost].lteq(purchase_cost_to))
    end
    results = results.where(availability: true) if value_to_boolean(availability)
    results
  end
end

app\models\product.rb

class Product < ApplicationRecord
end
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • maisumakun

    2017/04/06 18:12

    NoMethodErrorはどの行で、何に対して発生していますか?

    キャンセル

  • pecchan

    2017/04/06 18:14

    失礼しました。エラー画像を追加しました。

    キャンセル

回答 1

checkベストアンサー

+1

ActiveModelを利用しているのですか?
Rails5からというか、ActiveModelはRailsのversionが変わるたびに
かなり大きく変更されています。
value_to_booleanはRails3までだったと思います。
Rails5ではmodel層に
value_to_boolean関連等、Databaseとのデータの置き換えの記述は全消しして
attribute :column, :boolean
attribute :column1, :integer
などと書くだけで、大丈夫だと思います。
もしよろしければProduct.rbを表示してください。

もし検索をすることが目的ならば、gem ransackをお勧めします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/07 12:35

    moke様

    有難う御座います。
    ransackというのを使ってみます!

    rails5になって、やっと仕様が安定したんですね(+_+;)

    破壊的な変更・・・("゚д゚)

    Railsの勉強間もないですが、
    Railsと付き合っていくのって荒馬に乗るかのような印象を受けました。

    非常に強力なんですが扱いが難しい^^; 慣れるまでは・・・。

    キャンセル

  • 2017/04/07 13:03 編集

    rails2から3はかなり大変だったらしいです。
    3から4,4から5は普通かな、許せる範囲です。
    3から4は抜け道があったのですが、
    抜け道を使った人は5になるときにツケを払うことに...。

    まあ、基本、ごちゃごちゃ書いてたのが、リファクタリング感覚で直せるので
    そんなに苦痛ではないですし、過去のバージョンも保守されるので問題はないのですが…。

    荒馬ですか…。
    ある意味当たっている様な、違う様な…。
    初心者でも、すぐにセキュアでそれなりものもが作れる且つ
    どこまでもカスタマイズ可能の二面性の代償ですかね
    性格自体は気の利く優しいやつなんです…。
    そう、日本人の様なorz

    キャンセル

  • 2017/04/07 13:10

    moke様

    Railsの軌跡、参考になりました。

    だいたいはリファクタリング感覚なんですね。

    気の利く優しいやつ・・・・。
    なんだかニンマリしました( *´艸`)

    有難う御座いました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る