Search code examples
ruby-on-railsrubymodel

Model method not recognizing parameters


I'm building a rails app where users can search through "Playlists", which is an object containing a title, image, and tracks.

I've defined a search method in the Playlist model that takes one parameter: "query". It doesn't seem to recognize when a parameters are given, returning "expected 1 parameter, 0 given" error.

Playlist model (playlist.rb)

class Playlist < ApplicationRecord
  ...

  def self.search_all(query)
    if query
      self.where("title LIKE ?", "%#{search_all}%")
    else
      Playlist.all
    end
  end
end

Playlist controller (playlists_controller.rb)

class PlaylistsController < ApplicationController

  # GET /playlists or /playlists.json
  def index
    search = params[:search]
    
    if search_all
        @playlists = Playlist.search_all(search)
    else
        @playlists = Playlist.all
    end
  end
...

  private

    # Only allow a list of trusted parameters through.
    def playlist_params
      params.require(:playlist).permit(:title, :image, :search_all)
    end
end

How do I get my controller to "see" the parameters I've added?


Solution

  • There is a typo in your code:

    self.where("title LIKE ?", "%#{search_all}%")
    

    should be

    self.where("title LIKE ?", "%#{query}%")
    

    because that is the name of the argument passed to def self.search_all(query).

    Apart from that I suggest looking into ActiveRecord scopes. Which you can use to simplify your model and your controller.

    # in the model
    scope :search, ->(query) { where('title LIKE ?', '%#{query}%') if query.present? }
    
    # in the controller
    def index
      @playlists = Playlist.search(params[:search])
    end
    

    This works without a condition in the controller, because scopes return an instance of ActiveReord::Relation even when where wasn't called in the scope (in opposite to a similar implementation with a finder class method).

    Additionally, I suggest sanitizing the query string, as described in this answer.