Reputation: 10207
In my Rails app I have a User
class:
class User < ActiveRecord::Base
has_one :profile
has_one :sorting
has_many :people
has_many :companies
has_many :projects
has_many :invoices
has_many :payments
...
def move_to(user)
associations = %w(companies people projects invoices payments)
associations.each do |a|
send(a).update_all(:user_id => user.id)
end
%w(profile sorting).each do |a|
send(a).update_column(:user_id, user.id) # would like to use update_all here but not working
end
end
end
Is there a way to clean up my move_to
method, so that I can run update_all
on has_one
relations as well?
Upvotes: 0
Views: 1997
Reputation: 1403
You could use association_scope to get the ActiveRecord::Relation
object on has_one relation:
%i[profile sorting].each do |a|
association(a).association_scope.update_all(:user_id => user.id)
end
Upvotes: 0
Reputation: 3741
You can pass a block when declaring an association.
class User < ActiveRecord::Base
has_one :profile do
def update_all(attributes={})
update_column(attributes) unless attributes.empty?
end
end
end
You may be able to reduce this with a concern so that you only need to write it once. However, this seems like a very long way to go simply to reduce two loops to one.
Upvotes: 0
Reputation: 1934
You could use the relations instead of associations:
def move_to(user)
relations = [Profile, Sorting, Invoice, ...]
relations.each do |relation|
relation.where(user_id: self.id).update_all(:user_id => user.id)
end
end
But this would be dangerous if you have additional conditions on your associations.
Upvotes: 2