I'm having a trouble that I can't solve by myself, hope you can help me.
The problem
Currently I'm trying to get the Posts that user doesn't read yet, in other words, I want the posts that attends to posts.updated_at > viewed_posts.last_viewed_at. The date was been inserted right in the database, the problem is with the my ActiveRecord query.
Following is my query:
posts.joins(:viewed_posts).where(viewed_posts:
{ person_id: current_user.id, person_type: current_user.class.name})
.order('posts.updated_at > viewed_posts.last_viewed_at DESC')
But this doesn't work very well, appears that ActiveRecord ignores miliseconds, what change dramatically my result.
I have one post updated_at 2014-02-24 21:38:30.466789 and the same post was last_viewed_at 2014-02-24 21:38:30.497867 by one user. As you can see, this user already saw the post miliseconds later, and we can imagine that user don't will see this post, according to my query - but surprise! This post appears as one result of the query!
I can only imagine that ActiveRecord is ignoring miliseconds, or have another possible cause?
Possible solution
I found this answer, but this doesn't helped me because order don't accept two arguments (and I don't know how I can include this code in my where clause).
What can I do to solve my problem?
Related
I have created my first Rails Rake task which imports some data. It uses the URL to identify if the page needs to be updated or inserted. I am however having som really weird issue with some records being inserted multiple times instead, instead of just being updated.
My query looks like this:
existingCompany = Company.find_by_external_link(company.external_link)
I then look at
existingCompany.nil?
to see if the record needs to be created or updated. Some of the companies are not found by active record even though the external link exists. I have tried to print out the url and then look in the database (I use PostgreSQL) and it finds it correctly. The even weirder thing is that it doesn't happen to all records, only a few of them.
Anyone got an idea what might make ActiveRecord believe that a record doesn't exist?
You don't give a lot of information, but a couple of things to try:
How is company.external_link getting set? Either in the debugger or
a simple puts can tell you if it is what you think. For example
"http://www.ups.com/" != "https://www.ups.com/" !=
"http://www.ups.com"
You may need to be consistant on capitalization
or removing white space in company.external_link (.downcase, .strip)
Another thing to keep in mind is ActiveRecord creates a method Company.find_or_create_by_external_link which will do this in one step
I'm querying for test results which are associated with any test set that has a particular tag.
However, this query does not work:
(TestSet.Tags.Name = "foo")
What does work is:
(TestSet.Tags.Name contains "foo")
I would think the first query should work if the second one returns matches with the tag "foo". I presume this is a bug?
I can get around this problem by using the second query, but of course the problem is that this can match a tag named "foo2" as well, so my query can have extra results (potentially many more) and I have to filter them out. Additionally, now I need to have my query fetch the "Tags" as well, so every result I get back is larger because of it.
Yes, as user1195996 suggested this feels like a bug. Your same queries work as expected against defect or user stories. Please work with Rally Support on this issue so we can work to correct it.
I happened to see a line
Item.where(conditions).limit(10).order('created_at desc')
And I wonder it is similar to
Item.where(conditions).order('created_at desc').limit(10)
Seems ok as per new changes to rails 3, active record
But how about if we want, sample 10 items, *ordered by created_at*. This was my question #1
question 2 is 'limit' works within query, 'sample' does not..right?, it seems to be taken care of ruby array sample..right?
I recommend you check the railscast episodes 239 active relation walkthrough to understand how it works.
Basically, the internal work is done by Arel gem, activerecord object simply maintains the arel object when you do chaining. By the end of the day, it lets arel generate the sql statement, then it calls the find_by_sql with the generated sql statement.
The thing is that whether you called order before limit or the other way round, the generated sql statement is simply the same. Everything is executed by the database backend, activerecord simply parse the results and build up objects back.
I have photos which have_many comments.
I want to select whatever photos have recent comments and display those photos in a kind of "timeline" where the most recently commented photo is at the top and other photos fall below.
I tried this, and it worked on SQLite:
#photos = Photo.select('DISTINCT photos.*').joins(:comments).order('comments.created_at DESC')
However testing on PostgreSQL raises this error:
PGError: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
\n: SELECT DISTINCT photos.* FROM \"photos\" INNER JOIN \"comments\" ON \...
So, the problem is, I'm selecting Photos but ordering by recency of comments... and Postgre doesn't like that.
Can anyone suggest either:
A: How I can fix this query...
or
B: A different way to retrieve photos by the recency of their comments?
The important reason I'm doing it this way instead of through the comments model is I want to show each photo once with any recent comments beside it, not show each comment by itself with the same photos appearing multiple times.
Thanks!
Check out the :touch parameter of of the belongs_to association:
:touch
If true, the associated object will be
touched (the updated_at/on attributes
set to now) when this record is either
saved or destroyed. If you specify a
symbol, that attribute will be updated
with the current time instead of the
updated_at/on attribute.
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to
In your Comment model, therefore, you would have:
belongs_to :photo, :touch => :comments_updated_at
Now, in order to create a time line of photos with recently updated comments all you need to do is:
Photo.order('comments_updated_at DESC').all
Just be sure to add the "comments_updated_at" datetime field to your Photo model.
Make sense?
Just for the future readers of this question, the real answer to your SQL issue in SQlite vs Postgresql is that in the SQL "standard", every selected column needs to be in the GROUP BY or be an aggregate function.
https://www.techonthenet.com/sql/group_by.php (or whatever SQL ref you want to take a look at)
Your SQLite query used SELECT * instead of specific columns. That would have blown up with a similar error on most databases like Postgresql (MySQL, Maria, probably MSSQL Server). It's definitely invalid SQL grammar for a lot of good reasons.
Under the hood, I have no clue what SQlite does -- maybe it expands the * into fields and adds them to the GROUP BY under the hood? But its not a good SQL statement which is which it threw the error.
This returns the maxium value, not the complete record:
self.prices.maximum(:price_field)
And currently, I find the record like this:
def maximum_price
self.prices.find(:first, :conditions => "price = #{self.prices.maximum(:price_field)}" )
end
Is this the correct way ? Because the above needs two SQL statements to make it work, and it somehow does not feel right.
Ps. Additionally, I want that if more than one record has the same "maximum" value, then it should get the one with the latest updated_at value. So that would mean another SQL statement??
Pps. Does anyone know of a good or detailed reference for AREL and non-AREL things in Rails? The Rails Guide for ActiveRecord query is just not enough!
(I'm using Rails 3)
===UPDATE===
Using AREL I do the following:
self.prices.order("updated_at DESC").maximum(:price_field)
But this only gives the maximum value, not the complete record :(
Also, is the use of maximum() really AREL?
How about something like this?
self.prices.order("price DESC").first