0

I followed the Railscasts #37, very interesting. I tried to apply it to a search that already implies a scope and pagination. But it failed unsuccessfully. Being quite new at rails, I wonder if a better solution exists.

Here is my original controller, that works:

def index
  @business_rules = BusinessRule.pgnd(current_playground).order("hierarchy ASC").paginate(page: params[:page], :per_page => paginate_lines)

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @business_rules }
  end
end

But trying to add the search function as defined in the RailsCast fails:

@business_rules = BusinessRule.pgnd(current_playground).search(params[:search]).order("hierarchy ASC").paginate(page: params[:page], :per_page => paginate_lines)

Error message is: undefined method order for #<Array:0x007fbf8cc62ca0>

ekremkaraca
  • 1,453
  • 2
  • 18
  • 37
user1185081
  • 1,898
  • 2
  • 21
  • 46
  • I haven't seen the RailsCast in question, but it seems your `search` method returns an `Array`. For order or pagination to work, you need it to return a `ActiveRecord::Relation` or `ActiveRecord::CollectionProxy` type of object. – manu29.d Jun 05 '14 at 17:26

2 Answers2

1

Does your search function look like this, as in the railscast?

def self.search(search)
  if search
    find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
  else
    find(:all)
  end
end

If so, I'm guessing your getting back an array of results, which cannot be chained with additional query methods.

So when you use the query methods (where, order, limit, etc), it returns an ActiveRelation object, which is basically a proxy for your eventual result set. It won't actually hit your DB until you try to use the result set by calling .all, .first, .each, something like that.

You could write your search method like this instead:

def self.search(search)
  if search
    where('name LIKE ?', "%#{search}%")
  end
end

So if search is present, you'll scope your AR object down to the matching results. Otherwise you won't, which will have the same result as returning everything. Then you can still order those results, limit them, paginate them, whatever.

DVG
  • 17,392
  • 7
  • 61
  • 88
  • Hi DVG for this detailed explanation. I actually get no more error, but the index page is now empty (no record), and the form does not show up ! Any uncompatibility with will_paginate gem ? Thanks for your help. Fred – user1185081 Jun 08 '14 at 15:32
  • I wouldn't expect so, but it sounds like you are having some other issue. ARe you getting any errors? Do you have tests? – DVG Jun 09 '14 at 13:12
  • Actually, I noticed that the form_tag sentence starts with <% form_tag in the RailsCast, which I think is a former notation from Rails3. I wrote <%= form_tag to get it to be displayed. It now works fine. Thanks a lot ! – user1185081 Jun 10 '14 at 14:35
0

The final script for the search function created in the controller is:

def self.search(search)
  if not search.empty?
    where('name like ?', "%#{search}%")
  else
    where('1=1')
  end
end

Then it is possible to cahin the query methods as this:

    @business_rules=BusinessRule.pgnd(current_playground).search(params[:search]).limit(10)

For more explanations, please refer to RailsCast #37, and note that the syntax for inserting a from_tag is <%= form_tag ...

Thanks to all for your help,

Best regards,

Fred

user1185081
  • 1,898
  • 2
  • 21
  • 46