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
Related
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
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
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!
I need to fill an array of a search result that their information can be accessed from any model, controller or view. is it possible?
module AdsHelper
attr_reader :table
def initialize
#table = []
end
def add_ads_table(ads)
ads.each do |ad|
#table << ad
end
end
end
#table is the "public" array
class AdsController < ApplicationController
attr_reader :tabla
include AdsHelper
def index
order = sortable_column_order
if params[:search]
#ads = Ad.search(params[:search], params[:page],params[:sort])
add_ads_table(#ads)
else
#ads = Ad.paginate(:per_page => 4, :page => params[:page], :order => order)
add_ads_table(#ads)
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #ads }
end
end
end
after completing the array I want to show the information in a view of the same model Ad
Sounds like you're looking for a global variable to me. Just start your variable declaration with an $ instead of #, like this:
def initialize
$table = []
end
Use with care! Globals litering code can end up making a pretty impressive mess of things, not to mention end up with weird scenarios about them. Just a warning.
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|
%>