RelationToStruct
When one needs to use ActiveRecord to fetch specific values (whether subset columns of a model or arbitrary calculated columns), it's desirable to avoid the overhead of model instances and any associated callbacks.
ActiveRecord::Relation#pluck solves a similar problem but returns tuples; I wanted to be able to return Ruby structs to benefit from named instance methods.
Installation
Add this line to your application's Gemfile:
gem 'relation_to_struct'
And then execute:
$ bundle
Or install it yourself as:
$ gem install relation_to_struct
Examples
You can query either via direct SQL or from an ActiveRecord relation.
From an existing relation
UserPostsSummary = Struct.new(:user_name, :post_count)
relation = User.joins(:blog_posts).where(name: 'Hayek').group('users.id').select('users.name, COUNT(blog_posts.id)')
relation.to_structs(UserPostsSummary) # => array of structs
From raw SQL
UserPostsSummary = Struct.new(:user_name, :post_count)
sql = <<-eos
SELECT users.name, COUNT(blog_posts.id)
FROM users
LEFT OUTER JOIN blog_posts ON blog_posts.user_id = users.id
GROUP BY users.id
eos
ActiveRecord::Base.structs_from_sql(UserPostsSummary, sql) # => array of structs
ActiveRecord::Base.pluck_from_sql(sql) # => array of tuples
sql = <<-eos
SELECT users.name
FROM users
LIMIT 1
eos
ActiveRecord::Base.value_from_sql(sql) # => single value
sql = <<-eos
SELECT users.id, users.name
FROM users
LIMIT 1
eos
ActiveRecord::Base.tuple_from_sql(sql) # => [id, name]
Contributing
- Fork it ( https://github.com/jcoleman/relation_to_struct/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Test your changes (
bundle install && appraisal install && rake
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request