Postgres hstore and Rails sunspot solr - ruby-on-rails

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

Related

rails sunspot searchable enum

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.

rails sunspot solr not working with has_and_belongs_to_many

rails sunspot solr not working with has_and_belongs_to_many
events -- has_and_belongs_to_many --tags
searchable do
text :title, :boost => 5
text :description
text :tag_names do
tags.map(&:name)
end
end
In the above example its working with title and description only. not with tag_names.
well, i am assuming here that the tag_names is an array.. if that is the case, pls give it like this...
searchable do
text :title, boost: 5
text :description
text :tag_names, multiple: true do
tags.map(&:name)
end
end
(Try using the new hash notation... give boost: 5 instead of :boost => 5.. This is just a suggestion.. your code will work irrespective of the mechanism that u follow..)

Ruby present model not in DB

I would like to use a model in Rails but not store it in DB. For example let's say I have a RSS reader. I would download some RSS data from other site and then create objects with specific model and show them to use. I don't want to store those objects in databse though. How can I do it?
I think your problem might easily be solved by just creating a class, alternatively you can use ActiveModel, it allows for the same behaviour without storing it in the db.
class RssReader
#include any behaviour you like
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
end
There is a very nice railscast on this at:
http://railscasts.com/episodes/219-active-model
You can also check this out(Rails 4)
http://blog.remarkablelabs.com/2012/12/activemodel-model-rails-4-countdown-to-2013
You're looking for tableless models, there are plenty of questions on SO about this:
Rails model without database
Rails Model without a table
and a handy railscast!
http://railscasts.com/episodes/193-tableless-model
In rails 2.3 You can do this by this way:
class OrderSession < ActiveRecord::Base
def self.columns() #columns ||= []; end
column :orderable_id, :integer
column :orderable_type, :string
column :subscription, :boolean
column :interval, :integer
column :quantity, :float
column :number, :integer
column :only_with_main_cart, :boolean
column :start_on, :date
attr_accessor :choice_item
attr_accessor :interval_choice_item_1
attr_accessor :interval_choice_item_2
validates_presence_of :orderable_id
validates_presence_of :orderable_type
validates_presence_of :interval
validates_numericality_of :quantity, :greater_than => 0
validates_inclusion_of :subscription, :in => [true, false]
validates_inclusion_of :only_with_main_cart, :in => [true, false]
end
I am using this for storing cart information before user confirmation

Indexing a MongoDB on Heroku, with Rails and Mongoid

I have a Rails app running Mongoid on Heroku and I need to set up some indexes to make the database faster. I've tried to read about it several places and I know Mongoid has some built-in functions for indexing, but I'm not sure on what to apply them and how often to index.
It is mostly my Design-model I want to index:
scope :full_member_and_show, where(full_member: true).and(show: true).desc(:created_at)
scope :not_full_member_and_show, where(full_member: false).and(show: true).desc(:created_at)
embeds_many :comments
belongs_to :designer
search_in :tags_array
attr_accessible :image, :tags, :description, :title, :featured, :project_number, :show
field :width
field :height
field :description
field :title
field :tags, type: Array
field :featured, :type => Boolean, :default => false
field :project_number, :type => Integer, :default => 0
field :show, :type => Boolean, :default => true
field :full_member, :type => Boolean, :default => false
field :first_design, :type => Boolean, :default => false
What do I need to index, how exactly do I do it with Mongoid and how often should I do it?
ERROR UPDATE
If try to index the below:
index({ full_member: 1, show: 1 }, { unique: true })
It throws me this error:
Invalid index specification {:full_member=>1, :show=>1}; should be either a string, symbol, or an array of arrays.
You don't need to index periodically: once you've added an index, mongo keeps that index up to date as the collection changes. This is the same as an index in MySQL or Postgres (you may have been thinking of something like solr)
What to index depends on what queries you'll be making against your dataset. Indexes do carry some overhead when you do updates and consume disk space so you don't want to add them when you don't need them.
You tell mongoid what indexes you want by index, for example
class Person
include Mongoid::Document
index :city
end
There are loads of examples in the mongoid docs for the various kinds of indexes mongo supports.
Then you run
rake db:mongoid:create_indexes
This determines what indexes you want (based in the calls to index in your model) and then ensures that they exist in the db, creating them if necessary. In development you'd run this after adding indexes to your models. In production it makes sense to run this as part of your deploy (you only need to if you've added indexes since the last deploy but it's way easier to just do it systematically)
There's a lot of information about how mongo uses indexes in the documentation

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