Thinking Sphinx, associations are not working - ruby-on-rails

I have a model:
class Topic < ActiveRecord::Base
define_index do
indexes title, :sortable => true
indexes body
indexes tags(:name), :as => :tag_name
end
has_and_belongs_to_many :tags, :join_table => 'topic_tags', :order => 'tags.name asc'
end
When I run:
rake ts:rebuild
I get:
sql_range_query: Unknown column 'topics.name' in 'field list'
And my 'config/development.sphinx.conf' has this oddness:
sql_query = SELECT `topics`.`id` * 1 + 0 AS `id` , CAST(`topics`.`title` AS CHAR) AS
`title`, CAST(`topics`.`body` AS CHAR) AS `body`, CAST(`topics`.`name` AS CHAR) AS
`tag_name`, `topics`.`id` AS `sphinx_internal_id`, 1552019743 AS `class_crc`, '1552019743'
AS `subclass_crcs`, 0 AS `sphinx_deleted`, IFNULL(`topics`.`title`, '') AS `title_sort`
FROM `topics` WHERE `topics`.`id` >= $start AND `topics`.`id` <= $end GROUP BY
`topics`.`id` ORDER BY NULL
sql_query_range = SELECT IFNULL(MIN(`id`), 1), IFNULL(MAX(`id`), 1) FROM `topics`
So for some reason associations look bust, where have I gone wrong and how do I fix this?
(running rails 2.3.4 and latest thinking sphinx 1.2.11)

Trivial trap:
This works:
class Topic < ActiveRecord::Base
has_and_belongs_to_many :tags, :join_table => 'topic_tags', :order => 'tags.name asc'
define_index do
indexes title, :sortable => true
indexes body
indexes tags(:name), :as => :tag_name
end
end
associations must be defined prior to the index.

Related

Rails console : query to database

I have a model Report in which I defined those columns:
class Report < ActiveRecord::Base {
:id => :uuid,
:declarant_id => :uuid,
:reference => :integer,
:sent_at => :datetime,
:updated_by_id => :uuid,
:device_id => :string,
:created_at => :datetime,
:updated_at => :datetime,
:is_archived => :boolean,
:step_id => :uuid
}
and I want to filter the select query to get only the reports created 7 days ago, I defined this query related to some others inputs and methods :
r = Report.all.current.not_sent.only_finished_interventions.where("Report.created_at >= ?", 7.days.ago)
it not works !
when I do :
r = Report.all.current.not_sent.only_finished_interventions
I get the the requested reports.
can some one help to add the filter of 7.days.ago ?
I got this error in the rails c :
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing
FROM-clause entry for table "report" LINE 1: ... AND
"activities"."finished_at" IS NOT NULL) AND (Report.cre...
This should work:
.where("Reports.created_at >= ?", 7.days.ago)
Just make Report plural.
But I think Reports. is not necessary in your query bcs you don't join tables, so this should work too:
**`.where("created_at >= ?", 7.days.ago)`**

Filter rails record by 2 instances of child record model

I'm trying to filter a list of Products based on 2 tags,
class Product < ActiveRecord::Base
has_many :tags
end
class Tag < ActiveRecord::Base {
:id => :integer,
:created_at => :datetime,
:updated_at => :datetime,
:key => :string
}
How can I format a query statement that allows me to find a product which has 2 tags, one with key 'fragile', and one with key 'perishable'?
Product.joins(:tags).where("tags.key IN (?)", ['fragile', 'perishable']).group('products.id').having('COUNT(tags.id) = ?', 2)

Thinking Sphinx indexer condition

My models:
class Item < ActiveRecord::Base
belongs_to :group
scope :able, ->{joins(:group).where(:groups => {:disabled => [nil,false]}).order("position")}
end
class Group < ActiveRecord::Base
has_many :items
scope :able, ->{ where(disabled: [false,nil]).order('position') }
end
My item_index.rb
ThinkingSphinx::Index.define :item, :with => :active_record do
indexes title
# attributes
has created_at, updated_at, group_id, position
end
How i can index only Item where group.disabled is false or nil.
Example with where:
ThinkingSphinx::Index.define :item, :with => :active_record do
where "id = 1"
indexes title
# attributes
has created_at, updated_at, group_id, position
end
This will index only Item with id = 1
In your index definition:
# force join on groups table:
join group
# PostgreSQL
where "disabled = 'f' OR disabled IS NULL"
# MySQL
where "disabled = 0 OR disabled IS NULL"
I'd highly recommend on having a default value of true or false for your disabled column, thus avoiding null values.

Rails, Sphinx (thinking_sphinx) and sorting from associations

I have 3 models:
Stats (belongs_to :item)
t.integer :skin_id
t.integer :item_id
t.integer :rating
Item (has_many :stats)
and
Skin (has_many :stats)
Using thinking_sphinx i want to create a separate index, for items, sorted by :rating for particular :skin_id
So, i'm trying to:
define_index 'sort_by_rate' do
indexes stats(:rating), :as => :ratings, :sortable => true
end
But this, will generate an index for all :skin_id (in the Stat model), not for particular one.
In other words, i need to gather all items, sorted by Stat.rating, with Stat.skin_id == 1 (for example).
Here is the example of SQL:
"SELECT `stats`.* FROM `stats` INNER JOIN `items` ON `items`.`id` = `stats`.`item_id` WHERE `stats`.`skin_id` = 1 ORDER BY rating DESC"
ANy solutions is very appreciated!
Perhaps you should have in your define_index block:
has :skin_id
and then, when searching, filter by that. Something like this:
Item.search(:with => {:skin_id => skin.id}, :order_by => 'ratings ASC')

has_many :messages where user is recipient or author in one query

My Message model belongs_to author and recipient.
belongs_to :recipient, :class_name => "User", :foreign_key => "recipient_id"
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
Now what I would like to do is setting up a has_many relationship in the User model that is getting all messages where the user is ether author or recipient in a single query. How do I do something like that?
has_many :messages, :finder_sql => ['author_id = #{self.id} or recipient_id = #{self.id}']
However this breaks.
User.first.messages
User Load (0.6ms) SELECT "users".* FROM "users" LIMIT 1
Message Load (0.5ms) author_id = #{self.id} or recipient_id = #{self.id}
PGError: ERROR: syntax error at or near "author_id"
LINE 1: author_id = #{self.id} or recipient_id = #{self.id}
^
:author_id = #{self.id} or recipient_id = #{self.id} ActiveRecord::StatementInvalid: PGError: ERROR: syntax error at or near "author_id" LINE 1: author_id = #{self.id} or recipient_id = #{self.id}
Update:
Interpolating variables was removed from Rails 3.1. Now you have to use a proc
has_many :messages, :finder_sql => proc { "SELECT * FROM messages WHERE author_id = #{self.id} or recipient_id = #{self.id}" }
source
You cannot interpolate variables in single quotes.
'author_id = #{self.id} or recipient_id = #{self.id}'
should be
"author_id = #{self.id} or recipient_id = #{self.id}"

Resources