Deprecation warning: #apply_finder_options - ruby-on-rails

I get DEPRECATION WARNING: #apply_finder_options is deprecated. when trying this in my user.rb:
def User.search(search, page)
paginate page: page,
per_page: 10,
conditions: ['name LIKE ?', "%#{search}%"],
order: 'name'
end
Called through UsersController:
def index
#users = User.search(params[:search], params[:page])
end
The pagination is done with the will_paginate gem.
What is triggering the warning and how can I fix it? Been trying some googling, but I find the docs not too comprehensive!

I'm pretty sure you just need to pull the order and conditions options out of the paginate method and use Active Record for that instead:
def User.search(search, page)
order('name').where('name LIKE ?', "%#{search}%").paginate(page: page, per_page: 10)
end

Related

Links to change ordering of a posts loop

I'm trying to achieve links in my page that allow me to change the order that my posts display in. Similar to 'Recent', 'Hot' and 'Oldest' on Reddit.
I currently have by default
PostsController.rb
def index
#posts = Post.order('created_at DESC').all.paginate(page: params[:page], per_page: 20)
end
How would I go about adding links to a method to reverse the flow of posts to ASC or to display posts descending by a specific column on the model like views?
Jon
I'd create some scopes and a method in the model to handle all the possibilities,
# Post.rb
scope :recent, -> { order(created_at: :desc) }
scope :hot, -> { order(something: :desc) }
scope :oldest, -> { order(created_at: :asc) }
def self.sort_by(sort_param)
case sort_param
when 'recent'
recent
when 'hot'
hot
when 'oldest'
oldest
else
all
end
end
# controller
#posts = Post.sort_by(params[:order]).paginate(page: params[:page], per_page: 20)
Since I'm whitelisting, I don't really need to sanitize, any wrong param will return the default order.
If you want you could use #send and add method names to the whitelist array, but you need to make sure that the scope exists
def self.sort_by(sort_param)
if %w(recent hot oldest).include? sort_param
send sort_param
else
all
end
end
Use will_paginate gem in your app for Sorting in both directions and Paginate.Visit this link to implement it https://github.com/mislav/will_paginate.
firstly you want to remove the all so that pagination works better.
def index
#posts = Post.order('created_at DESC').paginate(page: params[:page], per_page: 20)
end
then you can use a variable to control the order. The important thing is to sanitise before passing to mysql.
def index
sort_by = ActiveRecord::Base::sanitize(params.permit(:sort_by))
#posts = Post.order(sort_by).paginate(page: params[:page], per_page: 20)
end

Rails 4 - Nested Resources

User has_many Tickets.
Ticket belongs_to User (ticket.user_id)
routes.rb
resources :users do
resources :tickets
end
rake routes
user_tickets GET /users/:user_id/tickets(.:format) tickets#index
users/index.html.erb
<%= link_to("View User's Tickets", user_tickets_path(user)) %>
users_controller.rb
private
def set_user
#user = User.find(params[:id])
#tickets = #user.tickets
end
tickets_controller.rb
def index
#search = Ticket.search(params[:q])
#tickets = #search.result.paginate(:page => params[:page], :per_page => 25)
render 'shared/tickets.html.erb'
end
When I hover over link, it shows .../users/[the selected user's id]/tickets
When it goes to the ticket/index page, it shows ALL tickets, not just the tickets with the selected user's id.
I'm pretty sure my route is incorrect, or it may be something else entirely. Any help is appreciated.
EDIT
I think my problem is that I need to call #tickets in the tickets_controller/index method a variety of ways, because I want to use that view for #tickets.all, #user.tickets, #facility.tickets, etc (to keep it DRY).
The same index list of tickets needs to change, based on the link from whence it came (whether it comes from the user list, showing a list of all tickets by that user, or from the facility list, showing a list of all tickets by that facility). I'm just doing something horribly wrong somewhere.
Possible solution I will try:
Maybe I need to create custom routes, like get 'users_tickets' => "users#users_tickets", then put the #tickets conditions in that method and call the shared/tickets.html.erb that way.
Sounds like you need to step through the association. Did you use
tickets_controller.rb
def index
#user = User.find(params[:user_id])
#tickets = #user.tickets
end
in the controller? If this doesn't help, can you post the controller code?
Aren't you trying to whittle down #tickets rather than do another query?
Right now you're redefining #tickets when they hit the tickets index, and it doesn't care that you defined #tickets as just belonging to that user on the users_controller. It just ignores that because you're using direct assignment in your tickets_controller index action. You probably want something like:
tickets_controller.rb
def index
#search = Ticket.search(params[q])
#tickets = #search.result.where(user: #user)
#tickets = #tickets.paginate(:page => params[:page], :per_page => 25)
end
Not tested, but I think that's more what you're wanting.
Ok - I think I need to review nested resources again, because I thought they did what I wanted automatically...or maybe they do, and I just don't get it yet.
In any case, I ended up creating a custom route and custom method in users:
routes.rb
get 'user_tickets' => "users#user_tickets"
users_controller.rb
def user_tickets
#user = User.find(params[:id])
#search = Ticket.where(:user_id => #user.id).search(params[:q])
#tickets = #search.result.paginate(:page => params[:page], :per_page => 25)
render 'shared/tickets.html.erb'
end
then, called:
<%= link_to("View Tickets", user_tickets_path(:id => user.id)) %>
I will do the same for facilities, departments, etc. Not sure this is the best way, but it works.
Thanks everyone for stimulating my brain cells.

ActiveRecord Relation error

def index
#users = User.order("name").page(params[:page]).per_page(5)
end
This is my UsersController where i try to view all users from database. Problem is because is see only this error:
undefined method `page' for #<ActiveRecord::Relation::ActiveRecord_Relation_User:0x000000044853d8>
Where is the problem?
You can do like this incase you have used will_paginate gem
#users = User.order("name ASC").paginate(:page => params[:page], :per_page => 5)
Take a look on the gem will_paginate
The usage of will_paginate is slight different than Kaminari. You should do:
#users = User.order('name').paginate(page: params[:page], per_page: 5)

Using Simple Search with Kaminari Pagination Gem

I am trying to apply pagination to my rails app using Kaminari. I am also incorporating a simple search form based on the Railscast Episode #37. When I try to apply the kaminari page and per methods I get the error 'undefined method page'. Below is the code I'm using.
posts_controller.rb
def index
#posts = Post.search(params[:search]).page(params[:page]).per(2)
end
post.rb
def self.search(search)
if search
find(:all, conditions: ['title || body LIKE ?', "%#{search}%"], order: "created_at DESC")
else
find(:all)
end
end
index.html.erb
<%= paginate #posts %>
When I remove the pagination the search works fine. When I remove the search the pagination works fine. I just can't seem to use them both and have the code function properly. Please advise if there is something in my code that I am missing that is causing this not to work properly.
In your case, you are returning array object from the search method not ActiveRecord::Relation object.
find(:all, conditions: ...) # find method will return an array object.
Add check in your controller,
def index
#posts = Post.search(params[:search])
if #posts.class == Array
#posts = Kaminari.paginate_array(#posts).page(params[:page]).per(10)
else
#posts = #posts.page(params[:page]).per(10) # if #posts is AR::Relation object
end
end
Kaminari pagination with an array https://github.com/amatsuda/kaminari#paginating-a-generic-array-object
for ActiveRecord::Relation object, checkout this http://railscasts.com/episodes/239-activerecord-relation-walkthrough

check if function is valid to prevent 'undefined method error' in rails

I am using a gem, will_paginate, to paginate contents on a rails site.
It's usage is: (from the official example)
## perform a paginated query:
#posts = Post.paginate(:page => params[:page])
# or, use an explicit "per page" limit:
Post.paginate(:page => params[:page], :per_page => 30)
## render page links in the view:
<%= will_paginate #posts %>
Now in some views, I will need the pagination but some views I don't. So when using a common layout to render out the content, the pages without pagination will display an error.
will_paginate undefined method error
Is there a way to check if will_paginate is a valid function before it the view tries to display it?
Thanks in advance,
You could make use of rescue.
For example :
<%= do_something rescue do_something_else %>
You can use defined? will_paginate or will_paginate #posts rescue _do_something_else_.
The defined? tells you if the function is defined, any you can use it in an if, the rescue handles the exception.

Resources