Rails3 records this year - ruby-on-rails-3

In Rails3 how do I retrieve all records that have a date of this year?
I'd like to retrieve all my "Projects" where the "date" is this year.
I would suspect it would be something similar to:
#projects_this_year = Project.where(:date.Time.year == Time.now.year)
or
#projects_this_year = Project.where(:date >= ?, Time.now.year)
I'm reading through the docs, but haven't quite figured this out yet.

You could do something like this (Assuming a MySQL DB):
#projects_this_year = Project.where("year(date) = ?", Time.now.year)
or better:
#projects_this_year = Project.where("year(date) = year(utc_timetamp())")
which doesn't require loading the time library.
For reference: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Edit
If you want it to be database independent then you can do something like this:
#projects_this_year = Project.where("date >= ?", Time.now.at_beginning_of_year)

You could also make this dynamic in the model if you needed specific months or years often or through params by expanding on #David's answer:
def self.get_year(date)
# sanitize if params
safe = ['2011', '2012', '2013']
if safe.include?(date)
where("year(created_at) = ?", Time.parse("#{date}-01-01 11:11:11 -0500").year)
else
scoped
end
end
EX:
Product.get_year('2012')
NOTE to get this to work on heroku please change the following:
where("date_part('year', created_at) = ?", Time.parse("#{date}-01-01 11:11:11 -0500").year
http://www.java2s.com/Code/PostgreSQL/Date-Timezone/datepartyeardate.htm

Related

Search for database objects created on a specific day?

I want to query my db for objects of an arbitrary model created on a certain day, what's a good way to do this?
In an sql query I used the following to query the objects created yesterday.
where (created_at AT TIME ZONE 'EDT') > (now() AT TIME ZONE 'EDT')::DATE - 1
and (created_at AT TIME ZONE 'EDT') < (now() AT TIME ZONE 'EDT')::DATE
I want to do the same thing in ruby with ActiveRecord calls.
Thanks!
An example, as a scope, for all items that were created today:
scope :created_today, -> { where('created_at between ? AND ?', Time.zone.now.beginning_of_day, Time.zone.now.end_of_day) }
More information at the PostgreSQL site
I would do the cast on the database and select the current date there, instead of doing it with a range. You can do this with DATE(created_at) (Will result in "2013-11-01") Then inject the param in the where:
Model.where("DATE(created_at) = ?", Date.today)
If it's used on more places then one it would be good to create a scope as Morner suggested:
scope :created_today { where("DATE(created_at) = ?", Date.today) }
with name:
scope :created_today_with_name lambda do |name|
where("DATE(created_at) = ? AND name = ?", Date.today, name)
end
or chain it:
scope :created_today_with_name lambda do |name|
where("DATE(created_at) = ?", Date.today).where(name: name)
end
Then call it as:
Model.created_today_with_name('Joe')

Rails Active Record Search - Name includes a word

Im trying to pull all records from a Project model that includes in the project_name the word 'Fox'. I can do an active record search and return specific project_names, like 'Brown Fox':
#projects = Project.where("project_name like ?", "Brown Fox")
But if I want to return all the names that INCLUDE 'Fox', this does not work unless the complete project name is 'Fox':
#projects = Project.where("project_name like ?", "Fox")
How do I do a search that returns all the objects with the word 'Fox' in the name?
Try using:
variable = "Fox"
Project.where("project_name like ?", "%#{variable}%")
You can use the SQL % operator:
#projects = Project.where("project_name like ?", "%Fox%")
Note that if you want your query to return results ignoring the word case, you can use PostgreSQL ilike instead of like.
Did you try ransack ?
With ransack you can do something like
#projects = Project.search(:project_name_cont => "Fox")
If you think it is too much for what you need. you can use the % operator as MurifoX said
Here's a version that will allow you to handle any number of input words and to search for all of them within a name. I was looking for this answer and didn't find the more complicated case, so here it is:
def self.search(pattern)
if pattern.blank? # blank? covers both nil and empty string
all
else
search_functions = []
search_terms = pattern.split(' ').map{|word| "%#{word.downcase}%"}
search_terms.length.times do |i|
search_functions << 'LOWER(project_name) LIKE ?'
end
like_patterns = search_functions.join(' and ')
where("#{like_patterns}", *search_terms)
end
end

SQL select distinct value

I'm trying to select the following data with the limited information. The problem is that when I have added the .select distinct section it has killed my query.
#activities = Availability.select.("DISTINCT user_id").where("team_id = ? and schedule_id = ?", current_user[:team_id], #next_game).last(5)
There's one too many dot's in there as the 'DISTINCT user_id' is the arguments for the select method call.
So:
Availability.select("DISTINCT user_id").where("team_id = ? and schedule_id = ?", current_user[:team_id], #next_game).last(5)
Also be aware that you're now only selecting one attribute and you'll get a partial representation of the classes back. To circumvent this just select the attributes you need later in the code.
Availability.select("DISTINCT(`user_id`), `team_id`").where("team_id = ? and schedule_id = ?", current_user[:team_id], #next_game).last(5)
etc.
Hope this helps.

Rails date without year

How can I find a record by date, but without the year?
this is what I have :
#date = Date.today
#article = Article.find_by_date(#date)
But really what I wanna do is search for an article that by only the month and the day. The year is not important.
Tested with SQLite:
Model.find(:all, :conditions => ["STRFTIME('%m-%d', field_name) = '?-?'", 12, 25])
The generated query illustrates how this finds everything where field_name is Christmas:
Model Load (16.1ms) SELECT "models".* FROM "models" WHERE (STRFTIME('%m-%d', field_name) = '12-25')
I also had success with the shorter "field_name LIKE '%-MM-DD'" but this was MySQL; according to its manual, it indeed uses strings to read and write dates. YMMV.
I suspect this is dependent on which database you're using. Different implementations have different names/syntax for the EXTRACT or DATE_PART function. On PostgreSQL, this one works:
Model.where('EXTRACT(month FROM field_name) = ? AND EXTRACT(day FROM field_name) = ?', 12, 25)
You can do:
Model.all.where(["DAY(`date`) = ? AND MONTH(`date`) = ?", Date.current., 12])
Simple!
A DB agnostic approach would be to add attributes to your model for date_month and date_day (and set them with a before_save callback). Something like:
before_save :set_date_day_and_month
def set_date_day_and_month
self.date_month = date.month
self.date_day = date.day
end
#untested
Then you can do straight-forward queries that wouldn't involve db-specific functions. Like:
Article.where('date_month = ? AND date_day = ?', 12, 25)
#for articles on Christmas
Or:
Article.where('date_month = ? AND date_day = ?', Date.today.month, Date.today.day)
#for articles on this date any year

Rails botches the SQL on a complex save

I am doing something seemingly pretty easy, but Rails is messing up the SQL. I could just execute my own SQL, but the framework should be able to handle this.
Here is the save I am trying to perform:
w = WhipSenVote.find(:first, :conditions => ["whip_bill_id = ? AND whip_sen_id = ?", bill_id, k])
w.votes_no = w.votes_no - 1
w.save
My generated SQL looks like this:
SELECT *
FROM "whip_sen_votes"
WHERE (whip_bill_id = E'1' AND whip_sen_id = 7)
LIMIT 1
And then:
UPDATE "whip_sen_votes"
SET "votes_yes" = 14, "updated_at" = '2009-11-13 19:55:54.807000'
WHERE "id" = 15
The first select statement is correct, but as you can see, the Update SQL statement is pretty wrong, though the votes_yes value is correct.
Any ideas? Thanks!
It would help to see the WhipSenVote model.
you can also use decrement!