1

I'm trying to search multiple columns in my model, by category. I was trying to use Model.scoped, but that was deprecated in Rails 4. Model.all seems to return all models, regardless of my other scopes. Is there an alternative to search the columns on my model and does my code look right? Would prefer to have one field to search multiple columns based on category. The search gems seem to be a bit overkill for what I'm trying to do. Below are my files.

vendor.rb (Edit from depa's comments)

belongs_to :category

def self.search(name, phone, email)
  scope = Vendor.all #still returns all in my model regardless of what I enter in search form.
  scope = scope.where(name: name) if name
  scope = scope.where(phone: phone) if phone
  scope = scope.where(email: email) if email
  scope
end

category.rb

has_many :vendors

vendors_controller.rb

def index
  @vendors = Vendor.order('created_at DESC')
end

def search
  @vendors = Vendor.search(params[:name], params[:phone], params[:email])
end

vendors/index.html.erb

<%= form_tag search_vendors_path, method: :get do |f| %>
  <%= text_field_tag :search, params[:search], placeholder: "Search Vendors" %>
  <%= select_tag 'category', options_for_select(Category.all.map{|el| [el.name, el.id]}) %>
  <%= submit_tag 'Search' %>
<% end %>
leejay100
  • 221
  • 1
  • 2
  • 12

1 Answers1

0

The equivalent in Rails 4 is simply .all. That's what you want when you just need a method to chain other queries onto.

def self.search(name, phone, email)
  scope = Vendor.all
  scope = scope.where(name: name) if name
  scope = scope.where(phone: phone) if phone
  scope = scope.where(email: email) if email
  scope
end

Reference: http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-all

You can confirm this in console (under Rails 4.1.4) by doing:

2.1.2 :001 > Vendor.all.class
 => Vendor::ActiveRecord_Relation

And, if you're worried that .all is going to eager load your relation, rest assured that is not the case. The eager loading behavior has been restricted to the .load method. You can also confirm this in console by doing:

2.1.2 :002 > scope = Vendor.all; scope = scope.where(name: "John Doe"); scope

You'll see it returns only the last scoped relation rather than all your model objects.

Marcelo De Polli
  • 28,123
  • 4
  • 37
  • 47
  • I'm not sure about that: http://stackoverflow.com/questions/18198963/with-rails-4-model-scoped-is-deprecated-but-model-all-cant-replace-it I tried Vendor.all already and it returns all my models. Tried Vendor.where(nil) already too. – leejay100 Aug 07 '14 at 10:20
  • Are you on Rails 4.0 or 4.1? Check this answer to the question you linked: http://stackoverflow.com/a/20791052/1512956 – Marcelo De Polli Aug 07 '14 at 12:21
  • Also, if you check the documentation, it says very clearly that `.all` should return an `ActiveRecord::Relation` scope object. It seems there was a bug in 4.0 that was fixed in 4.1. – Marcelo De Polli Aug 07 '14 at 12:23
  • I'm using 4.1.4. You're not wrong. It definitely works in console. Just doesn't work when using it in the app. – leejay100 Aug 07 '14 at 22:10
  • In my code above, even when I change it to scope = Vendor.all, I am still returning everything in my model. If the method in my model looks correct, then my issue must be in the controller/form? – leejay100 Aug 08 '14 at 08:42
  • I would make sure the right arguments are being passed to `self.search`, yes. – Marcelo De Polli Aug 08 '14 at 14:38