Using sunspot_solr search array of values - ruby-on-rails

Hi, I built a Ruby on Rails application with Sunspot Solr for searching.
#search = Answer.search do
with(:question_id, #question_ids)
paginate :page => 1, :per_page => Answer.count
end
return question_id
Here i want to search this Answer model using array of question_ids (ex: [1,2,3,4,5]).
How to do that? Kindly help me.

if your question and answer has association like
class Question < ActiveRecord::Base
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :question
end
then you can add searchable to your questions model like this
class Question < ActiveRecord::Base
searchable do
text :title, :body
text :answers do
answers.map { |answer| answer.body }
end
integer :questions_ids, :multiple => true
end
// your another methods
end
And in your index action
#search = Answer.search do
with(:questions_ids, #question_ids)
paginate :page => 1, :per_page => Answer.count
end
return question_id
I think it will help you.

Related

How to query across 2 different tables in Rails?

class Answer < ActiveRecord::Base
attr_accessible :question_id, :result, :user_id
end
class Question < ActiveRecord::Base
attr_accessible :prompt, :topic
end
I have the following 2 models above in my Rails app. I'd like to run a query that selects questions that have a certain topic (Math) but that are unanswered for a given user_id (result = "Unanswered").
I'm having trouble coming up with the query that would get this.
first_question = Question.where(:topic => "Math")
But I'm not sure how to incorporate the :result => "Unanswered" from the Answer table. Any advice?
To get all unanswered questions for user #1 under the MATH topic use:
Question.includes(:answers).where(:topic => 'MATH', 'answers.result' => 'Unanswered', 'answers.user_id' => 1)
If you want to just get the first unanswered question:
Question.includes(:answers).where(:topic => 'MATH', 'answers.result' => 'Unanswered', 'answers.user_id' => 1).first
I might create some scopes to make these easier to reuse:
class Question < ActiveRecord::Base
has_many :answers
scope :topic, lambda {|topic|
where(:topic => topic)
}
scope :unanswered_by, lambda { |user|
includes(:answers).where('answers.result' => 'Unanswered', 'answers.user_id' => user.id)
}
end
So you can then query like this:
user = User.last
Question.topic('MATH').unanswered_by(user)
You could use a joins to do an inner join between the questions and answers table, then merge a query for :result => "Unanswered":
Question.joins(:answer).where(:topic => "Math", :user_id => <user_id>).merge(Answer.where(:result => "Unanswered"))

will_paginate - Associations

I'm trying to paginate an Association but i'm missing something.
This is where i need the pagination with .paginate(:page => params[:page], :per_page => 25). If i understood correctly i have to make a variable in my controller to fetch the towns ?
<% #alliance.players.each do |p| %>
<% p.towns.each do |t| %>
...
<% end %>
<% end %>
What i'm calling:
Alliance ->
Players ->
Towns <--
Basically i'm stuck on how to paginate the Association in a 2nd level loop.
Maybe there is a better way of doing this.
The associations:
class Alliance < ActiveRecord::Base
# Primary Key
self.primary_key = 'grepo_id'
# Associations
has_many :players
end
class Player < ActiveRecord::Base
# Primary Key
self.primary_key = 'grepo_id'
# Associations
has_many :towns
belongs_to :alliance
end
class Town < ActiveRecord::Base
# Primary Key
self.primary_key = 'grepo_id'
# Associations
belongs_to :player, :foreign_key => :player_id
end
I've tried and read a lot but haven't found any solution.
I tried to make a variable in my Controller:
#alliance_towns = #alliance.players.towns.order("rank ASC").paginate(:page => params[:page], :per_page => 25)
so i can call #alliance_towns.each do {} but on this i'm getting
undefined method `towns' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Player:0x007f9268d91348>
What am i missing ?
You should use a join. Something like this:
#alliance_towns = Town.joins(:player).where('players.alliance_id = ?', params[:id]).order('rank ASC').paginate(:page => params[:page], :per_page => 25)

select specific attributes from array rails

I have post model
class Post < ActiveRecord::Base
acts_as_voteable
end
and Vote model
class Vote < ActiveRecord::Base
scope :for_voter, lambda { |*args| where(["voter_id = ? AND voter_type = ?", args.first.id, args.first.class.name]) }
scope :for_voteable, lambda { |*args| where(["voteable_id = ? AND voteable_type = ?", args.first.id, args.first.class.name]) }
scope :recent, lambda { |*args| where(["created_at > ?", (args.first || 2.weeks.ago)]) }
scope :descending, order("created_at DESC")
belongs_to :voteable, :counter_cache=>true,:polymorphic => true,:touch=>true
belongs_to :voter, :polymorphic => true
attr_accessible :vote, :voter, :voteable
# Comment out the line below to allow multiple votes per user.
validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]
end
when I get the post voters with these method
<% #post.voters_who_voted.each do |voter|%>
<%= voter.name %>
<% end %>
I load my database
how can I select only the user name and user id from these array?
update I changed my code I am using thumbs_up gem I pasted less code first to simplify the question
What do you mean by "load database"? If you want to select only id and name columns, then use #post.users.select([:id, :name]).each ...
Or is it about this problem (according to code that you provided)?
UPD.
voters_who_voted loads all voters and returns array https://github.com/bouchard/thumbs_up/blob/master/lib/acts_as_voteable.rb#L113. You have to add own association to Post model:
has_many :voters, :through => :votes, :source => :voter, :source_type => 'User'
It's just example, perhaps voters will clash with already existing method, if any.
Then use it here instead of voters_who_voted
did you try collect method ??
names = #post.users.collect(&:name)
ids = #post.user.collect(&:id)
If you want it to be related you can make a HASH with it. Id's mapped to the names.

Sunspot solr in rails need help to perform some query

I have a model User and Listing in my rails app. User has many listings and listing belongs to user. I also have a attribute name rating in user table. What I want is to search the keyword in Listing model and order it based on rating attribute of User model.
This is what I have in Listing model
searchable do
text :title, :default_boost => 3
text :description, :default_boost => 2
integer :category_id, :references => Category
integer :subcategory_id, :references => Subcategory
string :zipcode
time :created_at
double :user do
user.rating
end
end
And this is how I am trying to search
#search = Sunspot.search(Listing) do
keywords params[:q] do
fields :title
end
order_by THIS IS WHERE I NEED HELP
paginate :page => params[:page], :per_page => 20
end
You will need to add the keyword and rating attributes to the listing searachable method.
class Listing < ActiveRecord::Base
belongs_to :user
searchable do
text :keyword
integer :rating { user.rating }
end
end
Then in your search action in your controller
Listing.search do
fulltext params[:q]
order_by :rating, :desc
end
See http://sunspot.github.com/ for more examples.
Looking at your code, you need to change in your searchable method
double :user do
user.rating
end
to
double :rating do
user.rating
end

find_with_ferret , multiple model not working

I have 2 models A and B.
class A < ActiveRecord::Base
has_one :b
acts_as_ferret :fields => [:title,:description]
In a_cotroller, i wrote:
#search=A.find_with_ferret(params[:st][:text_search],:limit => :all).paginate :per_page =>10, :page=>params[:page]
The above title and description search is properly working.
class B < ActiveRecord::Base
belongs_to :a
Now,I want to perform a text search by using 3 fields; title, description(part of A) and comment(part of B). Where I want to include the comment field to perform the ferret search.Then,what other changes needed.
The documentation of find_with_ferret indicates that you simply code :store_class_name => :true to enable search over multiple models. While this is true there is a little more to it. To search multiple do the following:
#search = A.find_with_ferret(
params[:st][:text_search],
:limit => :all,
:multi => [B]
).paginate :per_page =>10, :page=>params[:page]
Notice the multi option. This is an array of the additional indexes to search.
Now to get his to work you have to rebuild your indexes after adding :store_class_name => :true to the index definitions.
class A < ActiveRecord::Base
has_one :b
acts_as_ferret :store_class_name => :true, :fields => [:title, :description]
end
OR...
You can simply include Bs fields in the index definition:
class A < ActiveRecord::Base
has_one :b
acts_as_ferret :fields => [:title, :description],
:additional_fields => [:b_content, :b_title]
def b_content
b.content
end
def b_title
b.title
end
end
This makes everything simple, but doesn't allow to search the B model independently of A.

Resources