I have a Ruby 2.2.2 app that uses ActiveRecord as the ORM (similar to Rails). I have two tables, "users" and "accounts", where "accounts" have belongs_to :user
. For a given user, I simply want to eager load the contents of the "accounts" table into a Ruby object (named user_accounts
) so I can perform operations like:
user_accounts.find_by_product_name("nameofproduct")
...without the find_by_product_name
method performing a SQL query. I simply want to preload all entries from the "accounts" table (that belong to a given user) into a Ruby object so I can minimize the number of SQL queries performed.
No matter how much documentation I read, I cannot figure out how to do this properly. Is this possible? If so, how?
If you don't want the ORM to re-query the database, then I think you are better of using the select
method added by the Enumerable mixin. Because if you try to use the find_by_*
methods, I think it will always send another query.
Here is an example of how it could be achieved.
# The accounts association will be loaded and cached the first time
@user.accounts.select { |account| account.name == "nameofproduct" }
# The next time, it is already loaded and will select from the previously loaded records
@user.accounts.select { |account| account.name == "nameofanotherproduct" }
I would store that accounts in a hash
instead of an array
, because lookups in a hash are much faster (in O(1)
) than in an array which only allows O(n)
.
group_by
helps you building that hash.
# assuming that @user.accounts returns all accounts
user_accounts = @user.accounts.group_by(&:name)
# querying the hash. use `first` to receive the first matching
# account (even if there is only one)
user_accounts['nameofproduct'].first
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.