Skip to content

Instantly share code, notes, and snippets.

@sudoremo
Last active March 4, 2024 15:23
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sudoremo/4204e399e547ff7e3afdd0d89a5aaf3e to your computer and use it in GitHub Desktop.
Save sudoremo/4204e399e547ff7e3afdd0d89a5aaf3e to your computer and use it in GitHub Desktop.
# This is a workaround for the rails issue described in
# https://github.com/rails/rails/issues/17368. If you use this,
# make sure you understand its code and what it does and what it
# doesn't.
#
# See below for an example.
# lib/lazy_ids.rb (i.e.)
module LazyIds
extend ActiveSupport::Concern
included do
after_save :persist_lazy_ids
end
def persist_lazy_ids
return unless @_lazy_ids
@_lazy_ids.each do |association, ids|
send(:"eager_#{association.to_s.singularize}_ids=", ids)
end
@_lazy_ids = {}
end
module ClassMethods
def lazy_ids(association)
alias_method :"eager_#{association.to_s.singularize}_ids=", :"#{association.to_s.singularize}_ids="
define_method "#{association.to_s.singularize}_ids=" do |ids|
@_lazy_ids ||= {}
@_lazy_ids[association] = ids
end
define_method association.to_s do
if @_lazy_ids && @_lazy_ids[association]
return self.class.reflect_on_association(association).klass.find(@_lazy_ids[association])
else
return super()
end
end
end
end
end
# Example:
class User
include LazyIds
has_many :groups_users
has_many :groups, through: :groups_users
lazy_ids :groups
end
u = User.first
u.group_ids = [1, 2, 3] # Aah, it does not save :)
u.save! # Now it does!
@jox
Copy link

jox commented May 25, 2020

Thanks! I needed to change line 37 from return super to return super() due to error "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.". (Ruby 2.5.1, Rails 5.2.4.1).

@sudoremo
Copy link
Author

Thanks! I needed to change line 37 from return super to return super() due to error "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.". (Ruby 2.5.1, Rails 5.2.4.1).

Thank you, the gist is updated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment