Rails 3 Pagination for NON-ActiveRecord results - ruby-on-rails

My rails 3 app uses sphinx to perform search on text files, and I return a collection of results on the landing page view: something like
<%= render :partial => "result", :collection => #results %>
What is the Rails way to do pagination for the results? I know there are plugins like will_paginate, but I'm not using ActiveRecord (my app doesn't even use a db).
Is a Javascript solution the best way to go? I want to also maintain REST in the url, ie "/search?query=hello&page=2"

Here is someone who has already done so: How to use will_paginate with non-ActiveRecord collection/array

Related

Accessing Views Within Ruby on Rails Application

I want to make a view for my website coded in RoR wherein all the available path are listed as links. Is there any way to access the views for various models from the program?
For example, something like:
<%model.views.each do |v| %>
<%= link_to v %>
<% end %>
You could use the sitemap_generator or dynamic_sitemaps gem to generate Sitemaps for your application.
You can use named routes, which allows you to create a link to a different part of your rails app, based on names you set in routes.rb. You can also include route parameters, too, which makes it easy to link to models.
In your routes.rb
get 'test_route/:id' => 'example#controller', as :test
In controllers/views:
link_to #example.name, test_path(id: #example.id)
Further reading on named routes
Im not sure why you want this :), but this will give you the routes
Rails.application.routes.routes
if you want to get all the paths as an array
Rails.application.routes.routes.collect {|r| r.path.spec.to_s }

Need to exclude pre and next buttons from kaminari pagination

I want to change kaminari pagination paginate helper format like
First,Prev - current page - Next,Last
Because its breaking my design with unwanted numbers.
I tried with all other helpers but no success.
Is there any way? Please let me know your thoughts.
Here's my thoughts. You need to go to the Kaminari GitHub page. That link leads to section about generating Kaminari partials, so you can edit them just like you want. Right from that page:
rails g kaminari:views default -e haml
Where haml is your template engine. You can replace it by erb, slim (depending on what you prefer to use).
Update. Here's a related question about customizing Kaminari templates.
Use Kaminari's themes
<%= paginate #users, :theme => 'my_custom_theme' %>
you need custom kaminari view files in
app/views/kaminari/my_custom_theme
And another simpler solution, what happen if you do this?
<%= paginate #users, :window => 0 %>
You can customize it a little more using CSS, each part of the pagination widget has some class or id, you can hide/show/modify them
[vidur#centos7-demo tukaweb]$ rails g kaminari:views default -e erb
Running via Spring preloader in process 25960
create app/views/kaminari/_first_page.html.erb
create app/views/kaminari/_gap.html.erb
create app/views/kaminari/_last_page.html.erb
create app/views/kaminari/_next_page.html.erb
create app/views/kaminari/_page.html.erb
create app/views/kaminari/_paginator.html.erb
create app/views/kaminari/_prev_page.html.erb
in the view:
<%= paginate #data %>

How to implement database search like this with Rails?

I am working on my first website using Ruby on Rails. The idea is a nutrition "search engine", where you search for a food and then the web app takes you to either a page with nutrition information about that food or a page of search results if no exact match exists.
So far, I have created the nutrition information database (using Postgresql) and added some test data. This is the command I used to create the scaffolding for the database:
rails generate scaffold Food name:string calories:decimal portion_name:string \
portion:decimal image_url:string description:text
I then created the index page. This is the command I used to create the index:
rails generate controller home index
I removed public/index.html and modified config/routes.rb to contain this line:
root :to => 'home#index'
After this, I added the search form to app/views/home/index.html.erb, like so:
<div id="search">
<h1>How many calories are in... ?</h1>
<%= form_tag("/search", :method => "get") do %>
<%= text_field_tag "q", nil, :class => "span6" %>
<%= submit_tag("Go", :name => nil) %>
<% end %>
</div>
Now, I would like to hook up this search form so that, if there is an exact match to the search query or one near match, the user is routed directly to a page displaying information (from the database) for that food. If there isn't an exact match, I would like the user to be presented with a page of results and links to the nutrition page for each result.
How can I implement this functionality? I have tried googling for articles about implementing search with Rails and I have watched a screencast, also, but none of the resources I have found are implementing quite what I want.
Here's a GitHub link to the project so far: https://github.com/robertseaton/nutrition-project.
I use Thinking-Sphinx for searching in Rails - Sphinx is an open source search server. You can define how you want your search to work right in Rails.
You can also use sunspot to cater to your needs of the search. Here is the github link of sunspot https://github.com/sunspot/sunspot .
Using sunspot you can specify what all items are going to be searchable like food, calories etc. and also give various weights to these items so that if there is a keyword match lets say between food and protien which result should be displayed at the top.
sunspot wiki at github has got lot of resources to get you started and it is very intuitive to implement :).
Thanks,

How to upgrade the :update=>'div_id' option of remote_form_for from Rails 2 to Rails 3?

I can't figure out how to upgrade this code from Rails 2 to Rails 3:
<% remote_form_for(item, :update => 'div_id') do |f| %>
...
I tried this:
<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" }, :update => 'div_id' do |f| %>
...
It creates the new item but it fails in updating the content within <div id="div_id"></div> tags. It seems Rails 3 no longer supports the ":update" option for a remote form_for. Any suggestion?
You could use RJS, but that's being deprecated too (and for good reason). The simplified, best-practices way to handle this in Rails 3+ is as follows (assuming jQuery):
# your_view.html.erb
<div id="receiver-id"></div>
<%= form_for :some_model, :remote => true, :id => 'form-id' do |f| %>
...
<% end %>
# application.js (or any other .js loaded on the page)
$(function(){
$('#form-id').bind('ajax:success', function(xhr, data, status){
$('#receiver-id').html(data);
});
});
The ajax:success hook gets called by the jquery-ujs (aka jquery-rails, aka rails-ujs) remote link/form handler. See for yourself. There are lots of other callbacks/hooks available for you to use, too. If you wanted to make this even more flexible, you could use live instead of bind, and bind to a class that dictates where the ouput goes (e.g. "sidebar") and then all remote links/forms with the sidebar class would have their HTML response go to div#sidebar.
The most straightforward way to do this would be to write a javascript view template, e.g. create.js.erb which would look something like this:
$('#div_id').html("<%= escape_javascript(render(#item)) %>");
(depending on your setup, of course, I'm assuming an #item variable and an associated _item partial)
Edit:
coreyward is right. This is the RJS way which is more of the old fashioned Rails 2.x "Rails way". It's probably more familiar, but has issues. Your specific case is one of them, actually, as typically you might bind to an HTML element to update using the record's id (e.g. div #item_1), and in the create case there is no id available beforehand, complicating matters.
Binding via clientside JS eliminates this issue. RJS works in something of a vacuum, making assumptions about the state of the client's HTML and having no access to it.
I know the question is old but I when migrating to Rails 3 I found a pretty good way of doing this, so I thought I would post it here in case anyone else is in a similar solution.
In layouts/update_page.js.erb I put this file:
$j('#<%=#update_div_id||"list_div"%>').html('<%= escape_javascript render(:partial => (#partial_div||"index"), :locals => #local_hash) %>');
This is mainly used for searches that use remote, so in the index action in the controller, I just added the following code.
respond_to do |format|
format.html
format.js {render 'layouts/update_page'}
end
Since remote is being used, it will always try to use javascript first, so it will render the update_page.js.erb file from above. For us, we almost always use the div#list_div on our index pages, so we update that by the default, however if you need to update something different, you can pass in #update_div_id, and if you need to render a different page, you can pass in #partial_div.
To clarify, for a lot of things, it is probably better practice to use the callbacks, but I found this to be a much easier way, when we had to migrate over nearly 100 of these calls.

Rails pagination of subset of a class

I have a rails app and I'm trying to set up pagination for a view of the Essays class. I'm new to rails... so I can do this for ALL of them, but I only want certain ones to be in this list (where all the essays are contained in Essay.find(Ranking.where(:user_id=>current_user.id).essay_id)).
home.html.erb contains (among other things):
`<%= will_paginate #essays%>
<ul class="users">
<%= render #essays %>
</ul>
<%= will_paginate #essays%>`
in the Pages Controller:
def home
#...
#essays = Essay.paginate(:page => params[:page])
end
I tried adding #essays=Essay.find(Ranking.where(:user_id=>current_user.id).essay_id) before the #essays=Essay.paginate(:page => params[:page]) but the method essay_id for the Ranking class is not available here. How do I get around this? Thanks!
This should work:
Essay.joins(:rankings)
.where(:rankings => {:user_id => current_user.id})
.paginate(:page => params[:page])
While this can be done with will_paginate. I've had some issues with this plugin for Rails 3. A much smoother solution, in my opinion, was to use another pagination plugin called Kaminari.
Assuming, essay_id is passed as a param, you could try:
#ranking = Ranking.where(:user_id => current_user.id, :essay_id => params[:essay_id]).page(params[:page]).per(10)
Or depending on your logic. If the essay object has already been identified in your controller:
#essay = Essay.find(1234)
#ranking = Ranking.where(:user_id => current_user.id, :essay_id => #essay.id).page(params[:page]).per(10)
And then, in your view:
<%= paginate #ranking %>
Even better, to get you started on Kaminari, you can view this rails cast. As noted from the rails cast:
The first-choice gem for pagination in
Rails is will_paginate, but the
currently released version doesn’t
support Rails 3. There is a
pre-release version available that
works but it hasn’t been updated for
several months. If will_paginate is no
longer in active development are there
any other gems we could use?
One alternative is Kaminari. This
seems to provide a cleaner
implementation of pagination and
offers several improved features, too,
so let’s try it in our application
instead.
Hope that helps!
Simply chain paginate method after find method:
#essays=Essay.find(Ranking.where(:user_id=>current_user.id).essay_id).paginate(:page => params[:page])

Resources