I have the following classes:
class User < ActiveRecord::Base
searchable do
text :full_name, boost: 3.0
text :about_me
join(:name, target: Nickname, type: :text, join: { from: :user_id, to: :id })
end
end
class Nickname < ActiveRecord::Base
searchable do
text :name
integer :user_id
end
end
What I would like to do is to search for a user by its full_name, about_me or has a nickname with the searched email.
I tried the following and I never get a result:
User.search { fulltext 'FrodoBaggings' }.results
User.search { fulltext 'FrodoBaggings'; fulltext 'Frodo', fields: [:name] }
User.search do
any do
fulltext 'Frodo Baggings', fields: [:full_name, :about_me]
fulltext 'Frodo Baggings', fields: [:name]
end
end
Related
The gem and version I am using for sunspot is:
sunspot_rails gem version 1.2.1
rails version 2.3.18
The query I am trying to search with and search method is something like this:
query_params = { :name => 'Joe Smith',
:email => 'joe.smith#email.com' }
How can I search a model with sunspot so that it searches via email or just name, since one can be blank for some searches (the below example did not work as expected)?
User.search do
fulltext(query_params[:name], :fields => :name)
fulltext(query_params[:email], :fields => :email)
end
* I have reindexed the models and the fields are all searchable within the model as well *
* EDIT *
The user.rb model is set up like this:
class User < ActiveRecord::Base
searchable do
text :name
text :email
end
end
Try the simple way like below
On the model
searchable do
text :name
text :email
end
On the controller of action
#search = User.search do |searcher|
name = [:email]
email= [:email]
searcher.any do
fulltext params[:name], :fields => name
fulltext params[:email], :fields => email
end
end
#users = #search.results #=> carry this to view
reindex and for good results restart the server
Hope it helps
Does any_of help?
User.search
any_of do
fulltext(query_params[:name], :fields => :name)
fulltext(query_params[:email], :fields => :email)
end
end
or
User.search do
any_of do
with(:name, query_params[:name])
with(:email, query_params[:email])
end
end
Try this due to it being a text field
User.search do
any_of do
keywords query_params[:name], :fields => [:name]
keywords query_params[:email], :fields => [:email]
end
end
Resource: https://github.com/sunspot/sunspot/wiki/Fulltext-search
Want to search for the title from the board with live_flag true.
class Board < ActiveRecord::Base
has_many :deals
include Tire::Model::Search
tire.mapping do
indexes :title, type: 'string'
indexes :deals do
indexes :title, type: 'string'
end
end
def to_indexed_json
{
:title => title,
:deals => {:title => self.deals.map(&:title)},
}.to_json
end
def self.search(params)
tire.search(load: true) do
query {string params[:query]+"*"}
filter :term, live_flag: true
sort { by :created_at, "desc" } if params[:query].blank?
end
end
end
Now it will not search anything.
It works properly when below code is used. Difference is that i have removed filter text from it.
def self.search(params)
tire.search(load: true) do
query {string params[:query]+"*"}
sort { by :created_at, "desc" } if params[:query].blank?
end
end
**But i want to get boards whose live_flag is true.**
Right now your index does not include the live_flag
just add live_flag to your to_indexed_json and mapping
tire.mapping do
indexes :title, type: 'string'
indexes :live_flag, type: 'boolean'
indexes :deals do
indexes :title, type: 'string'
end
end
def to_indexed_json
{
:title => title,
:live_flag => live_flag,
:deals => {:title => self.deals.map(&:title)},
}.to_json
end
I’m creating a Rails app that fetches photos from 500px’s API based on a search term and saves results to the db. I have two models: Photo and Search. I need to fetch the ID of the created search_term and save that to each photo, so I have an association between them.
Here is the Photo model.
class Photo < ActiveRecord::Base
self.per_page = 12
validates :uniqueid, :presence => true, :uniqueness => true
validates :name, :presence => true
validates :times_viewed, :presence => true
validates :rating, :presence => true
validates :votes_count, :presence => true
validates :favorites_count, :presence => true
validates :image_url, :presence => true, :uniqueness => true
has_one :search
end
Here is the Search model.
class Search < ActiveRecord::Base
validates :search_term, :presence => true
has_many :photos
end
I need to keep track of the number of times I’ve searched for a certain term, so I can ensure I’m not getting the same page of results back each time.
The controller for fetching the photos looks like this:
def index
#search = params[:search]
if #search
# I need to fetch the id of this search term
Search.create search_term: #search
#json_response = JSON.parse(get_access_token.get("/v1/photos/search?term=#{CGI.escape #search}&rpp=100&image_size=4&sort=times_viewed").body)
save_photos #json_response
end
end
Essentially, what I need to do is fetch the id of the created search term, and save that to each photo within this save_photos method.
def save_photos json_response
json_response['photos'].each do |photo|
Photo.create uniqueid: photo['id'],
name: photo['name'],
description: photo['description'],
times_viewed: photo['times_viewed'],
rating: photo['rating'],
votes_count: photo['votes_count'],
favorites_count: photo['favorites_count'],
image_url: photo['image_url'],
photo_taken: photo['created_at'],
category: photo['category'],
privacy: photo['privacy'],
comments_count: photo['comments_count'],
nsfw: photo['nsfw'],
# I’d like to save the id of the search term here
Search.create search_id: #search
end
end
Apologies if this is a duplicate question or is strikingly simple — I’ve come to a dead end with knowing what to search for with this problem.
Why don't you pass the id of the created search_term to save_photos method.
def index
#search = params[:search]
if #search
# I need to fetch the id of this search term
search = Search.create search_term: #search
#json_response = JSON.parse(get_access_token.get("/v1/photos/search?term=#{CGI.escape #search}&rpp=100&image_size=4&sort=times_viewed").body)
save_photos(#json_response, search.id)
end
end
def save_photos(json_response, search_id)
json_response['photos'].each do |photo|
Photo.create uniqueid: photo['id'],
name: photo['name'],
description: photo['description'],
times_viewed: photo['times_viewed'],
rating: photo['rating'],
votes_count: photo['votes_count'],
favorites_count: photo['favorites_count'],
image_url: photo['image_url'],
photo_taken: photo['created_at'],
category: photo['category'],
privacy: photo['privacy'],
comments_count: photo['comments_count'],
nsfw: photo['nsfw'],
# I’d like to save the id of the search term here
search_term_id: search_id
end
end
I have two models, Posts and Channels that I'm searching using Tire and ElasticSearch.
Currently, everything works just fine. However, I'm performing two searches and returning the results of both. I'd like to consolidate this into one – and search both models at the same time.
Below is the controller action I'm using to do just this:
def browse
#user = current_user
#channels = Channel.search(params)
#posts = Post.search(params)
end
Below is the Post model:
class Post < ActiveRecord::Base
attr_accessible :description, :name, :tag_list, :thumbnail_image, :status, :post_type, :subtitle, :summary, :visibility, :user
acts_as_taggable
has_one :publication
has_one :user, :through => :publication
has_many :subscriptions, dependent: :destroy
has_many :channel_post_connections, dependent: :destroy
has_many :channels, :through => :channel_post_connections
accepts_nested_attributes_for :channel_post_connections
accepts_nested_attributes_for :channels
accepts_nested_attributes_for :publication
accepts_nested_attributes_for :user
has_many :post_pages, dependent: :destroy
validates_presence_of :post_type, :name, :subtitle, :tag_list, :summary, :thumbnail_image, :if => :post_is_published?
include Tire::Model::Search
include Tire::Model::Callbacks
index_name 'posts_index'
def self.search(params)
tire.search(load: true) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
sort { by :created_at, "desc" } if params[:query].blank?
end
end
def to_indexed_json
to_json(methods: [:user_first_name, :user_display_name])
end
def user_first_name
self.user.first_name if self.user.present?
end
def user_display_name
self.user.display_name if self.user.present?
end
end
Below is the Channel model:
class Channel < ActiveRecord::Base
attr_accessible :title, :description, :cover_image, :status, :writable, :visibility, :thumbnail_image
has_one :channel_publication
has_one :user, :through => :channel_publication
has_many :channel_subscriptions
has_many :channel_post_connections
accepts_nested_attributes_for :channel_publication
accepts_nested_attributes_for :user
mount_uploader :thumbnail_image, ChannelThumbnailImageUploader
include Tire::Model::Search
include Tire::Model::Callbacks
index_name 'channels_index'
def self.search(params)
tire.search(load: true) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
sort { by :created_at, "desc" } if params[:query].blank?
end
end
def to_indexed_json
to_json(methods: [:user_first_name, :user_display_name])
end
def user_first_name
self.user.first_name if self.user.present?
end
def user_display_name
self.user.display_name if self.user.present?
end
end
Then, in my view, I have two loops:
- #posts.each do |post|
%h3
= post.name
- #channels.each do |channel|
%h3
= channel.title
Again – my goal is to execute one search, and display the results of posts and channels jumbled together using one loop.
Any help would be greatly appreciated... I'm pulling my hair out with this one!
UPDATE
Adding app trace...
app/controllers/posts_controller.rb:111:in `[]'
app/controllers/posts_controller.rb:111:in `block in browse'
app/controllers/posts_controller.rb:110:in `browse'
ANSWER
I replaced my browse action in the controller with:
def browse
#user = current_user
#search_items = Tire.search(['posts_index', 'channels_index'],{load: true}) do |search|
if params[:query].present?
search.query do |q|
q.string params[:query], default_operator: "AND"
end
end
search.sort { by :created_at, "desc" }
end
#results = #search_items.results
end
And then looped through #results in the view – and it worked!
You can use,
def browse
#search_items = Tire.search(['posts_index', 'channels_index'],{load: true}) do |search|
search.query do |q|
q.string params[:query], default_operator: "AND" if params[:query].present?
end
search.sort { by :created_at, "desc" } if params[:query].blank?
end
#results = #search_items.results
end
I am new to Ruby and Rails. I'm try to create a "Team" object that has a leader id and an array of users attached.
Problems
I am unable to attach the array of users to the team object
I am unable to define leader object, only store its id
Any help greatly appreciated
My Rails Models:
class Team
include Mongoid::Document
include Mongoid::Timestamps::Created
include Mongoid::Timestamps::Created
field :name
field :slug
field :description
field :leader
field :users, type: Array
field :holiday_days_per_year, type: Integer
field :hours_per_day, type: Integer
field :organisation_id, type: Integer
embeds_many :users
validates :name, :holiday_days_per_year, :presence => true
validates :holiday_days_per_year, :hours_per_day, :numericality => true
before_save :set_slug
def set_slug
self.slug = "#{name.parameterize}"
end
end
class User
include Mongoid::Document
include Mongoid::Timestamps::Created
include Mongoid::Timestamps::Created
field :slug
field :first_name
field :last_name
field :birth_date, type: Date
field :job_title
field :job_start_date, type: Date
field :job_probation_ends, type: Date
field :work_email
field :work_address
field :work_phone_number
field :personal_email
field :personal_address
field :personal_phone_number
field :organisation_id, type: Integer
# emails should be unique
validates_uniqueness_of :work_email, :personal_email
validates :first_name, :last_name, :birth_date,
:job_title, :job_start_date, :job_probation_ends,
:work_address, :work_phone_number,
:personal_address, :personal_phone_number,
:presence => true
# validates emails
validates_format_of :work_email, :personal_email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
belongs_to :team, :inverse_of => :users
before_save :set_slug
def set_slug
self.slug = "#{first_name.parameterize}-#{last_name.parameterize}"
end
end
controller action
# POST /teams
# POST /teams.json
def create
new_params = params.permit(
:name, :holiday_days_per_year, :hours_per_day, :leader, :users)
#team = Team.new(new_params)
if #team.save
render json: #team, status: :created, location: #team
else
render json: #team.errors, status: :unprocessable_entity
end
end
JSON Sent
{
holiday_days_per_year: 20
hours_per_day: 8
leader: "522cf27114bc38307a000004"
name: "Tester"
users: [
0: "522cf27114bc38307a000004"
1: "522d966214bc38659300000d"
2: "522dd21214bc38ac6b000011"
]
}
The object is created, but users and leader dont get saved, the object comes back as
{
_id: "522df8c714bc38ef3e000022",
created_at: "2013-09-09T16:35:19.405Z",
description: null,
holiday_days_per_year: 20,
hours_per_day: 8,
leader: "522d966214bc38659300000d",
name: "Tester",
organisation_id: null,
slug: "tester",
users: [ ]
}
In your model, redefine your "as_json" method with the following
class Team < ActiveRecord::Base
..
has_many :users
def as_json(options)
{ :name=>self.name, :leader=>self.leader, :users=>self.users }
end
end