Issue With Will Paginate and Index Action - ruby-on-rails

In my controller for the index action, I have;
def index
#documents = current_user.documents.all if current_user
end
Anything I add on the end of current_user I get an error. For example, I tried to add will_paginate which is simply adding .paginate(:per_page => 5, :page => params[:page]) to the end of the index action and adding <%= will_paginate #documents %> to the views.
Once I add the .paginate(:per_page => 5, :page => params[:page]) to the end of the index method, like this;
def index
#documents = current_user.documents.all if current_user.paginate(:per_page => 5, :page => params[:page])
end
I get a NoMethodError. Anybody know how to fix this?

Try
def index
#documents = current_user.documents.paginate(:per_page => 5, :page => params[:page]) if current_user
end

You're calling the method on the wrong object, here is the correct one:
#documents = current_user.documents.paginate(:per_page => 5, :page => params[:page]) if current_user

Related

Serialize JSON nested model in Ruby on Rails

I am new to rails and I have two models, one has a foreign key on the other model.
I created a controller and defined and index method which is working fine:
def index
#collections = Collection.all
render json: #collections
end
Which is rendering something like this:
[{"id":1,"title":"Collection
A","book_id":1,"created_at":"2016-04-10T18:41:32.709Z","updated_at":"2016-04-10T18:41:32.709Z"}]
I would like to transform that book_id field into a list of book objects, something like this:
[{"id":1,"title":"Collection A","books": [{"book_id": 1, "title:
"book_title"},],"created_at":"2016-04-10T18:41:32.709Z","updated_at":"2016-04-10T18:41:32.709Z"}]
Then I tried with:
def index
#collections = Collection.all
render :json => collections.as_json(
:include => { :book_title }
)
end
But is giving me syntax error and I cannot see how to do it properly in this doc http://guides.rubyonrails.org/layouts_and_rendering.html
I am using Rails 4.1.0
Try:
def index
#collections = Collection.all
render :json => #collections.as_json(
:include => :book
)
end
or if you would like just the :id and :title:
def index
#collections = Collection.all
render :json => #collections.as_json(
:include => {:book => {:only => [:id, :title]}}
)
end

How to avoid N+1 queries with Ransack

I've beeen using Ransack in one of my projects and also using Bullet to
spot some N+1 queries in my controllers. However, I'm not quite sure how to accomplish that while using Ransack.
There are two models involved, Patch and Image. And a Patch has_one Image.
The action code is the follow:
def index
#q = Patch.search(params[:q])
#patches = #q.result(distinct: true).order("code DESC").paginate(:page => params[:page], :per_page => 10)
end
Any thoughts?
This is working to me in a project.
def index
#q = Client.includes(zone: :user).ransack(params[:q])
#clients = #q.result.page(params[:page]).decorate
end
In your case should be
def index
#q = Patch.includes(:image).search(params[:q])
#patches = #q.result(distinct: true).order("code DESC").paginate(:page => params[:page], :per_page => 10)
end

Limit total messages displayed in the inbox

I can't seem to find the correct way to set a maximum number of messages to display in a users inbox without it disfiguring the pagination. I'm trying to make it so only the last 100 inbox messages are displayed from newest to oldest.
messages_controller.rb
class MessagesController < ApplicationController
def index
#messages = current_user.received_messages.paginate(:page => params[:page], :per_page => 15, :order => 'created_at DESC', )
end
using the will_paginate gem
<%= will_paginate #messages %>
def index
#messages = current_user.received_messages.paginate(:page => params[:page], :per_page => 15).order('created_at DESC').limit(100)
end
or try with
def index
#records = current_user.received_messages.order('created_at DESC').limit(100)
#messages = #records.paginate(:page => params[:page], :per_page => 15)
end
Hope this will work
But it is a good practice to first implement the active_records conditions, than the pagination's.
def index
#messages = current_user.received_messages.order(:created_at).reverse_order.limit(100).paginate(:page => params[:page], :per_page => 15)
end
Hope it will help.
I have this problem before, My fix was:
require 'will_paginate/array' # To paginate an array instead of ActiveRecord
class MessagesController < ApplicationController
def index
#messages = current_user.received_messages.limit(100).all.paginate(:page => params[:page], :per_page => 15, :order => 'created_at DESC') # I transform the resultset to an array using .all before the paginate
end

No field configured for Model with name 'image_filename'

I have a Model with 2 atrributes:
:image_filename
:yt_video_id
I have this code in my controller:
def index
#search = Model.solr_search do |s|
s.fulltext params[:search]
s.paginate :page => params[:page], :per_page => 2
s.with(:image_filename || :yt_video_id)
end
#model = #search.results
respond_to do |format|
format.html # index.html.erb
end
end
in my model.rb Model I have this in searchable:
searchable do
string :image_filename, :yt_video_id
end
I want filter :image_filename OR :yt_video_id any are not "nil". I mean, both attributes must have a mandatory value.
but I get the error:
Sunspot::UnrecognizedFieldError in ModelsController#index
No field configured for Model with name 'image_filename'
The problem was fixed with the following steps:
(This solution works fine for me. I hope this solution can help you too.)
In model.rb you can not write this syntax:
searchable do
string :image_filename, :yt_video_id
end
You must write this syntax:
searchable do
string :image_filename
string :yt_video_id
end
In your models_controller.rb in index action:
def index
#search = Model.solr_search do |s|
s.fulltext params[:search]
s.paginate :page => params[:page], :per_page => 2
s.any_of do
without(:image_filename, nil)
without(:yt_video_id, nil)
end
end
#model = #search.results
respond_to do |format|
format.html # index.html.erb
end
end
I have used the any_of method.
To combine scopes using OR semantics, use the any_of method to group restrictions into a disjunction:
Sunspot.search(Post) do
any_of do
with(:expired_at).greater_than(Time.now)
with(:expired_at, nil)
end
end
You can see in https://github.com/sunspot/sunspot/wiki/Scoping-by-attribute-fields

How to use will_paginate with a nested resource in Rails?

I'm new to Rails, and I'm having major trouble getting will_paginate to work with a nested resource.
I have two models, Statement and Invoice. will_paginate is working on Statement, but I can't get it to work on Invoice. I know I'd doing something silly, but I can't figure it out and the examples I've found on google won't work for me.
statement.rb
class Statement < ActiveRecord::Base
has_many :invoices
def self.search(search, page)
paginate :per_page => 19, :page => page,
:conditions => ['company like ?', "%#{search}%"],
:order => 'date_due DESC, company, supplier'
end
end
statements_controller.rb <irrelevant code clipped for readability>
def index #taken from the RAILSCAST 51, will_paginate podcast
#statements = Statement.search(params[:search], params[:page])
end
I call this in the view like so, and it works:
<%= will_paginate #statements %>
But I can't figure out how to get it to work for Invoices:
invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :statement
def self.search(search, page)
paginate :per_page => 19, :page => page,
:conditions => ['company like ?', "%#{search}%"],
:order => 'employee'
end
end
invoices_controller.rb
class InvoicesController < ApplicationController
before_filter :find_statement
#TODO I can't get will_paginate to work w a nested resource
def index #taken from the RAILSCAST 51, will_paginate podcast
#invoices = Invoice.search(params[:search], params[:page])
end
def find_statement
#statement_id = params[:statement_id]
return(redirect_to(statements_url)) unless #statement_id
#statement = Statement.find(#statement_id)
end
end
And I try to call it like this:
<%= will_paginate (#invoices) %>
The most common error message, as I play with this, is:
"The #statements variable appears to be empty. Did you forget to pass the collection object for will_paginate?"
I don't have a clue what the problem is, or how to fix it. Thanks for any help and guidance!
Solved -
I moved the invoices pagination into Statement's controller, like this:
def show
#statement = Statement.find(params[:id])
#TODO move the :per_page stuff out to a constant
#invoices = #statement.invoices.paginate :per_page => 10,
:page => params[:page],
:order => 'created_at DESC'
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #statement }
end
end
and call it in the view like this (code trimmed for readability>
<div id="pagination">
<%= will_paginate #invoices %>
</div>
<table>
<%# #statement.invoices.each do |invoice| -
shows all invoices with no pagination,
use #invoices instead%>
<%
#invoices.each do |invoice|
%>

Resources