rails sunspot searchable enum - ruby-on-rails

How to make enum in rails searchable with sunspot?
enum type: [ :restaurant, :travel, :hotel ]
searchable do
text :name, :boost => 5
text :description
integer :type
time :created_at
end
my controller:
#search = Product.search do
fulltext params[:search]
end
still no results, any idea?

You can change the searchable field definition from an integer to a string, and use with(:field, params[:search_query]).
model:
searchable do
string :enum_field
end
controller:
#search = Product.search do
with(enum_field: params[:search_query])
end
EDIT: Also, it just occurred to me that you might need to rename your enum column, as ActiveRecord uses type to signify Single Table Inheritance.

Related

Rails 4 and gem sunspot cannot order correctly

Im getting this error:
Sunspot::UnrecognizedFieldError in SitesController#products
No field configured for Product with name 'created_at'
here is my model Product.rb
class Product < ActiveRecord::Base
searchable do
text :name
text :description
text :specification
string :name
end
end
and here is a mehod in my controller:
def list_all_products
#search = Product.search do
fulltext params[:search]
order_by :created_at, :desc
end
#products = #search.results
end
the name field in my table products is a string. I defined in searchable products both for text and string. Why I still getting an error like this? thank you.
just add time :created_at in your model
class Product < ActiveRecord::Base
searchable do
text :name
text :description
text :specification
time :created_at
string :name
end
end

Postgres hstore and Rails sunspot solr

I have an application which relies heavily on the hstore type in postgres. The Issue I can't seem to get over is making the hstore searchable in sunspot. Here is some code I am working on
class Post < ActiveRecord::Base
# properties is type hstore
%w[price condition website].each do |key|
store_accessor :properties, key
end
...
searchable :auto_index => false, :auto_remove => false do
text :title, :boost => 5.0
integer :category
integer :subcategory
# this is whats giving me the problem
string :properties["price"]
end
end
I have tried adding different types but nothing seems to work. Is this a feature not yet supported?
Hstore is basically a hash it stores keys and values so all you have to do is iterate over the the keys and look them up.
Here is the working code:
searchable :auto_index => false, :auto_remove => false do
text :title, :boost => 5.0
integer :category
integer :subcategory
%w[price condition website].each do |key|
string key.to_sym do
properties[key]
end
end
end
hopefully in the future they'll have support for
hstore :properties

Tire/Mongoid Single Table Inheritance - Searching over mutliple models

I'm trying to get STI working with tire/mongoid since hours. I hope someone can help me.
I've two models with different indexes. It should be possible to search both indexes over Event.search but also to search only the appropiate index with CoursePlan.search.
First Model: Event
# encoding: utf-8
class Event
include Mongoid::Document
include Mongoid::Timestamps
include Tire::Model::Search
include Tire::Model::Callbacks
# rest of class omitted...
# Elasticsearch
index_name "events" # Indexname /initializers/tire.rb
mapping do
indexes :_id, :index => :not_analyzed
indexes :title
indexes :place
indexes :description
indexes :fill_out
indexes :current_user_keyword, analyzer: "keyword"
end
Second Model: CoursePlan
# encoding: utf-8
class CoursePlan < Event
include Mongoid::Document
include Mongoid::Timestamps
include Tire::Model::Search
include Tire::Model::Callbacks
include TimeHelper
# rest of class omitted...
# Elasticsearch
index_name "course_plans"
tire.index.add_alias "events"
mapping do
indexes :_id, :index => :not_analyzed
indexes :title
indexes :place
indexes :description
indexes :fill_out
indexes :user_email
indexes :course_title
indexes :course_area
indexes :course_user_email
indexes :date
end
I've tried already the solution from richarddong, see tire issue #178. But this only seems to work under some circumstances.
Is there a working solution for this problem? Maybe i just got something wrong.
Thank you for your time.
Please check this answer,
Search multiple models with Tire and ElasticSearch
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

Tables in DataMapper w/ Rails not Inheriting Correctly

I'm using DataMapper in Rails, replacing ActiveRecord and am trying to do some single table inheritance. The problem is, sqlite3 seems to be reading all of my inherited tables weird, and so I get some strange errors when trying to create an instance of that table in ruby.
I am using a model, ServerFile, to represent any uploaded or generic file that I want instanced in my database. I have another model, Upload, that extends that and represents an Upload from a user. I have two more models extending from ServerFile, Thumbnail, and UploadThumbnail, to represent a generic Thumbnail and a Thumbnail for an upload accordingly.
The error I keep getting is DataObjects::IntegrityError (server_files.upload_id may not be NULL) when I try to create an instance of an Upload like this:
upload = Upload.new(
filename: uploaded_io.original_filename,
path: path.to_s,
content_type: uploaded_io.content_type,
token: rand_token())
upload.member = #member
upload.title = params[:title]
upload.description = params[:description]
upload.save
And here are my models:
class ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :type, Discriminator
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
end
class Upload < ServerFile
property :title, String
property :description, Text
has n, :topics, through: Resource
has n, :subjects, through: Resource
has n, :downloads
has n, :comments, 'UploadComment'
has n, :ratings, 'UploadRating'
belongs_to :member
has 1, :thumbnail, 'UploadThumbnail', required: false
end
class Thumbnail < ServerFile
##IMAGE_EXTENSIONS = [:'png', :'jpg', :'jpeg', :'gif', :'svg', :'cgm']
validates_with_method :filename, :is_valid_image?
def is_valid_image?
##IMAGE_EXTENSIONS.each do |ext|
return true if /[\w\d\.\_\-]+\.#{ext.to_s}/ =~ #filename
end
[false, 'Invalide image type.']
end
end
class UploadThumbnail < Thumbnail
belongs_to :upload
end
And here is my sqlite schema for the table 'server_files' (and btw, when I list my tables, 'uploads' isn't listed among them):
sqlite> .schema server_files
CREATE TABLE "server_files" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "token" VARCHAR(50), "filename" VARCHAR(50), "path" TEXT, "content_type" TEXT, "type" VARCHAR NOT NULL, "created_on" DATE, "created_at" TIMESTAMP, "updated_on" DATE, "updated_at" TIMESTAMP, "title" VARCHAR(50), "description" TEXT, "member_id" INTEGER NOT NULL, "upload_id" INTEGER NOT NULL);
CREATE UNIQUE INDEX "unique_server_files_path" ON "server_files" ("path");
CREATE UNIQUE INDEX "unique_server_files_token" ON "server_files" ("token");
There is no need for an upload_id column on the server_files table. Because Upload inherits from ServerFile, this would essentially be self-referential. The column type with type Discriminator will be set to Upload in the database when the model is successfully saved. That being said, if you want to set a custom upload_id anyways, you can do it with a callback like this:
before :create, :generate_upload_id
def generate_upload_id
generated_upload_id = <do something>
attribute_set(:upload_id, generated_upload_id) unless upload_id
end
Otherwise, simply write a migration that removes the upload_id column from the server_files table
Source: http://datamapper.org/docs/misc.html
DataMapper for some reason just didn't like my superclass ServerFile. When I broke it up, it worked perfectly! (:
class Upload < ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
property :title, String
property :description, Text
has n, :topics, through: Resource
has n, :subjects, through: Resource
has n, :downloads
has n, :comments, 'UploadComment'
has n, :ratings, 'UploadRating'
belongs_to :member
has 1, :thumbnail, 'UploadThumbnail', required: false
end
class Thumbnail < ServerFile
include DataMapper::Resource
property :id, Serial
property :token, String, unique_index: true
property :filename, String
property :path, Text, unique: true
property :content_type, Text, length: 5..200
property :type, Discriminator
property :created_on, Date
property :created_at, DateTime
property :updated_on, Date
property :updated_at, DateTime
##IMAGE_EXTENSIONS = [:'png', :'jpg', :'jpeg', :'gif', :'svg', :'cgm']
validates_with_method :filename, :is_valid_image?
def is_valid_image?
##IMAGE_EXTENSIONS.each do |ext|
return true if /[\w\d\.\_\-]+\.#{ext.to_s}/ =~ #filename
end
[false, 'Invalide image type.']
end
end
class UploadThumbnail < Thumbnail
belongs_to :upload
end

Replacement for column_names when using Mongoid with rails 3 and dry_crud

I've been doing a spike on Rails 3 and Mongoid and with the pleasant memories of the auto scaffolding in Grails I started to look for a DRY view for ruby when I found:
http://github.com/codez/dry_crud
I created a simple class
class Capture
include Mongoid::Document
field :species, :type => String
field :captured_by, :type => String
field :weight, :type => Integer
field :length, :type => Integer
def label
"#{name} #{title}"
end
def self.column_names
['species', 'captured_by', 'weight', 'length']
end
end
But since dry_crud depends on self.column_names and the class above doesn't inherit from ActiveRecord::Base I have to create my own implementation for column_names like the one above. I would like to know if it possible to create a default implementation returning all of the fields above, instead of the hard coded list?
Why would you go through the trouble of doing all that when there's an in-built method?
For Mongoid:
Model.attribute_names
# => ["_id", "created_at", "updated_at", "species", "captured_by", "weight", "length"]
Short of injecting a new method in Mongoid::Document you can do this in your model.
self.fields.collect { |field| field[0] }
Update : Uhm better yet, if you fell adventurous.
In the model folder make a new file and name it model.rb
class Model
include Mongoid::Document
def self.column_names
self.fields.collect { |field| field[0] }
end
end
Now your model can inherit from that class instead of include Mongoid::Document. capture.rb will look like this
class Capture < Model
field :species, :type => String
field :captured_by, :type => String
field :weight, :type => Integer
field :length, :type => Integer
def label
"#{name} #{title}"
end
end
Now you can use this natively for any model.
Capture.column_names

Resources