How can I constrain search result? - ruby-on-rails

I'm trying to constrain the result by genre_id which is the column in Communities table.
But the end of the line in communities_controller says error.
Why? How can I fix this?
communities_controller.rb
#search = Community.search do
fulltext params[:search]
paginate :page => params[:page], :per_page => 5
end
#communities = #search.results
#communities = #communities.find_by_genre_id(params[:genre])

You should watch this video: http://railscasts.com/episodes/278-search-with-sunspot
It will help you.
Here is the sample code he uses:
Model: article.rb
searchable do
text :name, :boost => 5
text :content, :publish_month
text :comments do
comments.map(&:content)
end
time :published_at
string :publish_month
end
def publish_month
published_at.strftime("%B %Y")
end
Search algorithm:
#search = Article.search do
fulltext params[:search]
with(:published_at).less_than(Time.zone.now)
facet(:publish_month)
with(:publish_month, params[:month]) if params[:month].present?
end
#articles = #search.results
I am not familiar with sunspot, but it looks like your error (unrecognized field) might be resolved by including :genre_id in your model, like this:
searchable do
integer :genre_id
...
end
So your new search would look something like:
#search = Community.search do
fulltext params[:search]
with(:genre_id, params[:genre_id])
paginate :page => params[:page], :per_page => 5
end

Related

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

Issue With Will Paginate and Index Action

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

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

sunspot with i18n framework in rails 3.2

I'm using sunpost gem for search in my rails project.
I have now two languages in my app:
I18n.default_locale = :en
LANGUAGES = [
['English',
'en'],
["EspaƱol".html_safe, 'es']
]
I have in my post.rb model, a language attribute that contains the value "es" for spanish language or value "en" for english language.
I have in posts_controller in index action the next method:
def index
#search = Post.solr_search do |s|
s.fulltext params[:search]
s.keywords params[:search]
s.order_by :created_at, :desc
s.paginate :page => params[:page], :per_page => 20
end
#posts = #search.results
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.js
end
end
I get the current language with I18n.locale.to_s I get with this code "es" or "en"
My question is: How can I only show the results for the language currently in use by user in my website?
Thank you very much!
It would be very helpful if you could post the searchable block in the post model. But until then, I will take a stab at it.
Your Post model should look something like the following:
class Post < ActiveRecord::Base
searchable do
...
string :language
...
end
end
Where you are indexing the language the post is written/stored in.
Then your controller you use the language field as a filter. It should look like:
def index
#search = Post.search do |s|
s.keywords params[:search]
s.with(:language, I18n.locale.to_s) if I18n.locale.present?
s.order_by :created_at, :desc
s.paginate :page => params[:page], :per_page => 20
end
#posts = #search.results
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.js
end
end
and there you have it!

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