Thinking-Sphinx Grouping Error - ruby-on-rails

I have have the meeting model which belongs to the project:
class Project < ActiveRecord::Base
has_many :meetings
end
class Meeting < ActiveRecord::Base
belongs_to :project
define_index do
join project
indexes agenda
indexes project.name. :as => :project_name
end
end
I attempt to search with grouping:
Meeting.search("stuff", :group_by => 'project_id', :group_function => :attr)
I get the following error:
group-by attribute 'project_id' not found
Any suggestions?
Many Thanks.

This is just a wild guess based on the examples in the ThinkingSphinx docs (http://freelancing-god.github.com/ts/en/searching.html#grouping), but perhaps you need to include the attribute to be grouped by in the indexing.
Try adding has project_id to your define_index.

Related

Thinking Sphinx Rails Multiple Association

I have the following models
class Product < ActiveRecord::Base
belongs_to :sub_category
end
class SubCategory < ActiveRecord::Base
belongs_to :category
has_many :products
end
class Category < ActiveRecord::Base
has_many :sub_categories , -> { where("activate = 1") }
end
I need to index my products table.I need to search using category name(which is in category table) and subcategory name(in subcategories table)
ThinkingSphinx::Index.define :product , :with => :active_record do
indexes description
indexes name
indexes merchant_name
indexes sub_category(:sub_category) , :as => :sub_category_name
indexes category(:name) , :as => :cat_name
has sub_category_id
end
The category(:name) is failing.The subcategory is working fine.
Could somebody please help.I tried sub_category.category(:name) but thats also failing
Error Message
ERROR: index 'link_core': sql_range_query: You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near 'AS cat_name, products.id AS
sphinx_internal_id, 'Product' AS `sphinx_internal_' at line 1
(DSN=mysql://root:***#localhost:3306/xxxx_dev_phase4)
name should be passed as a chained method, not as an argument
indexes sub_category.category.name , :as => "category_name"
Thanks to the owner Pat for helping me out
concerned github thread

Rails Triple Join

I have 3 models Report, Server, and Platform. I need to execute a query that involves triple joining all 3 models and making the query based on that. But I get the following error whenever I try to triple join
ActiveRecord::ConfigurationError: Association named 'platform' was not found; perhaps you misspelled it?
Here are my models
Report
class Report < ActiveRecord::Base
belongs_to :server
delegate :company_id, :to => :server
class << self
def method(url, base_url)
Report.joins(:server).joins(:platform).where(:platforms => {:company_id => 5}).all
end
end
end
Server
class Server < ActiveRecord::Base
has_many :reports
belongs_to :platform
end
Platform
class Platform < ActiveRecord::Base
attr_accessible :company_id
has_many :servers
end
Try this: (note the s in platform it is needed because the table names are plural):
Report.joins(:server => :platform).where(:platforms => {:company_id => 5}).all

Filtering a relation in Rails

I have this relation in my Product model:
has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature
So I can do Product.features
which works fine. But I want to be able to filter that by fields in the feature table, when and if necessary. For example in pseudo code:
find all product features where feature is comparable
compare is a bool field on the feature.
I have been trying for 2 hours solid and cannot figure it out (without writing a new query completely). I can't figure out how to access the feature table's fields from the Product.features relation, as it seems it can only filter on product_features fields.
This is what I have come up with so far:
def features_compare
features.feature.where(:compare => true)
end
But it just says feature is not a valid method, which I understand.
Edit
I have updated my model so the relationships are clearer:
product.rb:
class Product < ActiveRecord::Base
belongs_to :company
belongs_to :insurance_type
has_many :product_features
has_many :reviews
attr_accessible :description, :name, :company
end
product_feature.rb:
class ProductFeature < ActiveRecord::Base
belongs_to :product
belongs_to :feature
delegate :name, :to => :feature
attr_accessible :value
end
feature.rb
class Feature < ActiveRecord::Base
attr_accessible :name, :compare
end
I want to be able to query the product_features that belong to a product and feature where Feature.compare is true. Something like this:
product.rb
def features_compare
product_features.where(:compare => true)
end
This throws an error because compare in in the Feature model, not ProductFeature. I have tried the following in product_feature.rb:
delegate :compare, :to => :feature
but I didn't help.
I will adding a bounty to this in a few hours so please please help me!
find all product features where feature is comparable is just
ProductFeature.joins(:feature).where(:feature => {:compare => true})
You can make that a bit more reusable by introducing a scope:
#in product_feature.rb
scope :with_feature_like, lambda do |filter|
joins(:feature).where(:feature => filter)
end
#elsewhere
ProductFeature.with_feature_like(:compare => true)
#all the product features of a certain product with at comparable features
some_product.product_features.with_feature_like(:compare => true)
Finally, if you want all products with product features with comparable features, you want something like:
Product.joins(:product_features => :feature).where(:feature => {:compare => true})
which of course you can also turn into a scope on Product.
This seems like a has_many :through relationship. Try changing this:
has_many :features, :class_name => 'ProductFeature', :source => :product_feature, :include => :feature
to this:
has_many :product_features
has_many :features, :through => :product_features
As long as your ProductFeature model has this:
belongs_to :product
belongs_to :feature
And you have the appropriate columns on product_features (product_id, feature_id), then you should be able to access that product's features and all the attributes on both Product and ProductFeature.
See here:
http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
EDIT: Here's how to filter by feature fields.
Product.joins(:features).where(:features => {:name => "Size"})
#product.each |p| { p.features.where(:comparable => true) } is probably your best bet here, but I'm open to being enlightened.

Search by record id with ultrasphinx

I'm trying to search by record id with ultrasphinx on Rails 2.3.8
In my model i tried the following:
class Offer < ActiveRecord::Base
is_indexed :fields => [{:field => 'id', :as => 'offer_id'}]
end
and
class Offer < ActiveRecord::Base
is_indexed :fields => ['id']
end
And I search with
Ultrasphinx::Search.new(:query => "1691")
It doesn't return any results, while searching for other indexed fields does.
Wow. a blast from the past.
Whilst I shifted to ThinkingSphinx after starting off with UltraSphinx, are you sure that you shouldn't be using
class Offer > ActiveRecord::Base
is_indexed :fields => ['id']
end
maybe try that for now and then figure out how to do the AS after.

Rails: Query to get recent items based on the timestamp of a polymorphic association

I have the usual polymorphic associations for comments:
class Book < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Article < ActiveRecord::Base
has_many :comments, :as => :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
end
I'd like to be able to define Book.recently_commented, and Article.recently_commented based on the created_at timestamp on the comments. Right now I'm looking at a pretty ugly find_by_SQL query to do this with nested selects. It seems as though there must be a better way to do it in Rails without resorting to SQL.
Any ideas? Thanks.
For what it's worth, here's the SQL:
select * from
(select books.*,comments.created_at as comment_date
from books inner join comments on books.id = comments.commentable_id
where comments.commentable_type='Book' order by comment_date desc) as p
group by id order by null;
Sometimes it's just best to add a field to the object of which you are commenting. Like maybe a commented_at field of datetime type. When a comment is made on an object, simply update that value.
While it is possible to use SQL to do it, The commented_at method may prove to be much more scalable.
Not sure what your method has looked like previously but I'd start with:
class Book < ActiveRecord::Base
def self.recently_commented
self.find(:all,
:include => :comments,
:conditions => ['comments.created_at > ?', 5.minutes.ago])
end
end
This should find all the books that have had a comment created on them in the last 5 minutes. (You might want to add a limit too).
I'd also be tempted to create a base class for this functionality to avoid repeating the code:
class Commentable < ActiveRecord::Base
self.abstract_class = true
has_many :comments, :as => :commentable
def self.recently_commented
self.find(:all,
:include => :comments,
:conditions => ['comments.created_at > ?', Time.now - 5.minutes])
end
end
class Book < Commentable
end
class Article < Commentable
end
Also, you might want to look at using a plugin to achieve this. E.g. acts_as_commentable.

Resources