🧚 주목! Beekeeper Studio는 빠르고 현대적이며 오픈 소스 데이터베이스 GUI입니다 다운로드
September 12, 2024 작성자: Matthew Rathbone

Using SQL Functions in Active Record

Most SQL databases provide functions to extract parts of a date. For instance, PostgreSQL uses EXTRACT(DOW FROM date), where DOW stands for “day of the week,” returning values from 0 (Sunday) to 6 (Saturday).

Let’s consider a Task model with a created_at column. Our goal is to fetch records that were created on weekdays only. We’ll use Active Record’s querying capabilities to achieve this.

# app/models/task.rb
class Task < ApplicationRecord
  scope :weekdays_only, -> { where("EXTRACT(DOW FROM created_at) BETWEEN 1 AND 5") }
end

Explanation:

  • EXTRACT(DOW FROM created_at): Extracts the day of the week from the created_at timestamp.
  • BETWEEN 1 AND 5: Limits the selection to Monday through Friday.

Using Ruby’s Date Methods with Active Record

If you want to strictly use Ruby’s Date methods, you can modify the code to filter records after fetching them from the database, but this is not efficient for larger datasets.

# app/models/task.rb
class Task < ApplicationRecord
  def self.weekdays_only_ruby
    all.select { |task| task.created_at.on_weekday? }
  end
end

Explanation:

  • This method first fetches all records from the database and then filters them using Ruby’s on_weekday? method.
  • task.created_at.on_weekday?: This converts the created_at timestamp to a Ruby Date object and checks if it’s a weekday (Monday through Friday).

Example Usage:

Task.weekdays_only_ruby

Note: This approach can be inefficient because it fetches all records from the database first, then processes them in memory. It’s recommended for small datasets. If you’re working with larger datasets, the SQL solution will be much more efficient.

Combining Conditions with Active Record

You might want to filter records by weekdays and a specific condition, like a status. This is possible by chaining scopes:

# app/models/task.rb
class Task < ApplicationRecord
  scope :weekdays_only, -> { where.not("EXTRACT(DOW FROM created_at) IN (0, 6)") }
  scope :completed, -> { where(status: 'completed') }
end

Example Usage:

Task.weekdays_only.completed

Querying Across Different Time Zones

When dealing with time zones, ensure the created_at timestamps are converted appropriately. Use the AT TIME ZONE clause in SQL for accurate comparisons.

# app/models/task.rb
class Task < ApplicationRecord
  scope :weekdays_only_in_timezone, ->(timezone) {
    where("EXTRACT(DOW FROM created_at AT TIME ZONE ?) BETWEEN 1 AND 5", timezone)
  }
end

Example Usage:

Task.weekdays_only_in_timezone('UTC')

Handling Other Databases

Different SQL databases may use different functions for date extraction:

  • MySQL: DAYOFWEEK(created_at)
  • SQLite: strftime('%w', created_at)

Make sure to adjust your queries according to the database being used:

# Example for MySQL
scope :weekdays_only, -> { where("DAYOFWEEK(created_at) BETWEEN 2 AND 6") }

After implementing these scopes, querying for Task.weekdays_only would result in a collection of tasks that are only created on weekdays. Here’s an example:

tasks = Task.weekdays_only
tasks.each do |task|
  puts task.created_at
end

Output:

2024-08-26 10:30:00 UTC  # Monday
2024-08-27 11:45:00 UTC  # Tuesday
2024-08-28 09:00:00 UTC  # Wednesday

Conclusion

Filtering Active Record results to include only weekdays is straightforward by leveraging SQL functions and Ruby methods to extract parts of a date.

Other articles you may enjoy:

Beekeeper Studio는 무료 & 오픈 소스 데이터베이스 GUI입니다

제가 사용해 본 최고의 SQL 쿼리 & 편집기 도구입니다. 데이터베이스 관리에 필요한 모든 것을 제공합니다. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio는 빠르고 직관적이며 사용하기 쉽습니다. Beekeeper는 많은 데이터베이스를 지원하며 Windows, Mac, Linux에서 훌륭하게 작동합니다.

Beekeeper의 Linux 버전은 100% 완전한 기능을 갖추고 있으며, 기능 타협이 없습니다.

사용자들이 Beekeeper Studio에 대해 말하는 것

★★★★★
"Beekeeper Studio는 제 예전 SQL 워크플로를 완전히 대체했습니다. 빠르고 직관적이며 데이터베이스 작업을 다시 즐겁게 만들어 줍니다."
— Alex K., 데이터베이스 개발자
★★★★★
"많은 데이터베이스 GUI를 사용해 봤지만, Beekeeper는 기능과 단순함 사이의 완벽한 균형을 찾았습니다. 그냥 작동합니다."
— Sarah M., 풀스택 엔지니어

SQL 워크플로를 개선할 준비가 되셨나요?

download 무료 다운로드