Created
May 13, 2015 16:48
-
-
Save jameskerr/69cedb2f30c95342f64a to your computer and use it in GitHub Desktop.
Preview an update to a Rails Model without saving anything to the database.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This class calls collection.build on each association that you specify in the @@variables, | |
# then calls assign_attributes on the attributes specific to this model. | |
# | |
# This class was created after I asked this question on stackoverflow. | |
# http://stackoverflow.com/questions/30109549/rails-preview-update-associations-without-saving-to-database | |
class PreviewEventUpdate | |
attr_accessor :params, :nested_params, :event | |
@@ids_keys = [:audience_ids, :group_ids, :location_ids, :user_ids].freeze | |
@@attributes_keys = [:occurrences_attributes, :ticket_types_attributes, :meta_urls_attributes].freeze | |
def initialize(params, event = Event.new) | |
@params, @event = params, event | |
@nested_params = {} | |
separate_nested_ids | |
separate_nested_attributes | |
end | |
def build | |
@event.assign_attributes(@params) | |
@nested_params.each do |key, attributes| | |
assocation_name = key.to_s.gsub(/_id|_attributes/, '').to_sym | |
@event.send(assocation_name).send(:build, attributes) | |
end | |
@event | |
end | |
private | |
def separate_nested_attributes | |
@@attributes_keys.each do |key| | |
next unless @params[key] | |
attributes = @params.delete(key) | |
@nested_params[key] = remove_destroyed_associations(attributes.values) | |
end | |
end | |
def separate_nested_ids | |
@@ids_keys.each do |key| | |
next unless @params[key] | |
@nested_params[key] = attributes_from_ids(key, @params.delete(key)) | |
end | |
end | |
def attributes_from_ids(key, ids) | |
ids.reject!(&:empty?) | |
klass = key.to_s.split('_ids').first.classify.constantize | |
klass.find(ids).map(&:attributes) | |
end | |
def remove_destroyed_associations(attributes) | |
attributes.reject!{ |obj| obj[:_destroy] == "1" } | |
attributes.each { |obj| obj.delete(:_destroy) } | |
attributes | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment