I want to check if there was a blank period that have no posts.
I wrote like this:
Post.all.pluck(:date).sort.each_cons(2).any?{|i,j| (i - j).abs > 7 }
Is there a better implementation?
I'm not good at database functions. Is there a function for it in Postgresql.
Albeit expensive, you could do a cross join (which really is a cartesian join) and calculate directly in the database. Also, here I assume that the columns are Datetime fields instead of Date.
For MySQL
Post.
joins('CROSS JOIN posts p2').
where('TIMESTAMPDIFF(DAY, date, p2.date) > 7').
present?
Note that the difference needed to be converted to days if you want 7 days period.
For Postgres, do check out the relevant function at the postgres datetime docs. You might have to do something like this:
EXTRACT(DAY FROM ABS(d1 - d2))
Related
My initial thought was:
user.humans.where("created_at = ?", 10.days.ago)
Though, this seems to be looking for the record created 10 days ago at the exact time when the statement is called. I want to collect the records created on that day, regardless of their time.
Is anyone aware of a convenient way to do this? Let me know if I need to elaborate.
Thanks.
You'll probably want to use a range here, as I assume this is a datetime column.
User.humans.where("? <= created_at AND created_at <= ?", 10.days.ago.beginning_of_day, 10.days.ago.end_of_day)
You'll also want to make sure you're setting the time zone of your Rails application so that you're explicit about which time period you consider to be the 10th day.
Whichever DBMS you are using will have a method to convert a datetime to a date. You should then compare this to a date in ruby. For example, if your DBMS is MySQL you could say
user.humans.where("date(created_at) = ?", 10.days.ago.to_date)
If you're not using MySQL then you should be able to google converting a datetime to a date in your DBMS of choice.
Original question:
Let's say I have 10 users in my database, and I want to get the 6th (or 3rd, or 8th, whatever) user based on sorted created_at date. How can I do this?
Edited question:
Let's say I have 10 users in my database, and I have a certain user, how can I determine wich nth user it is if I sort them on created_at date? (so user X is the nth user of all user based on created_at)
Sorry about the confusion!
This should work: (obviously have to change the offset value as needed)
User.order(:created_at).limit(1).offset(6)
Ok, the edited question makes this a bit more complex. Not sure if ActiveRecord is the right thing to use here. Some databases haw a kind of virtual "rownumber" which you could use for this. But lets assume we don't have that. SQL can't do that natively as such, so you could only count the number of records that are 'less' than what you look for.
Assume we have found the relevant User as user.
Then we could do:
User.where("created_at < :created_at", created_at: user.created_at).count
At least the best I can come up with.
User.order("created_at DESC").limit(1).offset(6)
or
User.order("created_at DESC").limit(1).offset(6)
It's work like :
select * from users order by created_at DESC LIMIT 5 OFFSET 30;
I have a model A which uses Rails timestamps and a attribute called ttl which represents the time in minutes between each update of the record.
I want to select all records that should be updated ergo:
WHERE (Time.now - updated_at).to_minutes > ttl)
I've been trying to use variations of Feed.where("(?-updated_at) > ttl", Time.now).to_a but I've not succeeded yet. Can someone help me with the query?
The reason is, that databases can't do time calculations just like arithmetic calculations.
You have to use the time function of the DB, unfortunately there is no standard.
In MySQL you could use
Feed.where("TIMESTAMPADD(MINUTE,ttl,updated_at)<?",Time.now)
I have a table which contains a column "discussion_duration" where I am storing certain times in seconds (6 hours = 21600). I would like to sort this table by 'created_at' + 'discussion_duration'.
I can add created_at and discussion_duration in ruby and it returns a date. However since the parameters in the rails .order() is raw sql, I'm not sure how to add these two fields then sort by the output.
Any help would be much appreciated.
edit: Actually this is probably what you're looking for. You'll need to use your database specific date/time functions to do it and here's a mysql example.
.order('TIMESTAMPADD(SECOND, discussion_duration, created_at)')
I have a Practice model that is storing start_time, end_time and day.
That information (like the rest of the site) will need to be displayed in 3 different
languages.
Start_time and end_time are both stored as Datetime types in the DB.
Day is not yet implemented, but will be shown as a select box. I have see people suggest an array of constants and storing it as an integer in the DB. While that seems reasonable, I am having trouble imagining that working well with different languages (using either I18n or Globalize2).
What is the cleanest way to implement this so it works well in different languages?
I can't see a good reason to store the days of the week in the database; I'd be surprised if such names will change and we are talking about 7 * 3 strings, that is a small amount of data to handle for your application.
i18n is the way to go. You can browser this repository to find day_names already traslated in different languages.
If you can't store or calculate the day of the week from the start and end DateTime objects, then I would recommend using an ENUM in the database - this causes the data to be stored as an integer - which takes up less space and is easier to index, and the conversion to the string types is done automatically for you so that you can query and insert strings, but the actual database values are integers.
Definitely do not store these values as strings though, it's harder to deal with them and they take up more space.