Module: Effective::CrudController::Save

Included in:
Effective::CrudController
Defined in:
app/controllers/concerns/effective/crud_controller/save.rb

Instance Method Summary collapse

Instance Method Details

#commit_action(action = nil) ⇒ Object

Based on the incoming params or passed action. Merges all options.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 6

def commit_action(action = nil)
  #config = (['create', 'update'].include?(params[:action]) ? self.class.submits : self.class.buttons)

  config = self.class.submits
  ons = self.class.ons

  commit = config[params[:commit].to_s]
  commit ||= config.find { |_, v| v[:action] == action }.try(:last)
  commit ||= config.find { |_, v| v[:action] == :save }.try(:last) if [nil, :create, :update].include?(action)
  commit ||= { action: (action || :save) }

  on = ons[params[:commit].to_s] || ons[action] || ons[commit[:action]]

  on.present? ? commit.reverse_merge(on) : commit
end

#duplicate_resource(resource) ⇒ Object

Should return a new resource based on the passed one



108
109
110
111
112
113
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 108

def duplicate_resource(resource)
  return resource.duplicate if resource.respond_to?(:duplicate)
  return resource.duplicate! if resource.respond_to?(:duplicate!)
  return resource.deep_dup if resource.respond_to?(:deep_dup)
  resource.dup
end

#notify_exception(exception, resource, action) ⇒ Object



80
81
82
83
84
85
86
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 80

def notify_exception(exception, resource, action)
  if defined?(ExceptionNotifier)
    ExceptionNotifier.notify_exception(exception, env: request.env, data: { resource: resource, action: action })
  else
    raise(exception)
  end
end

#reload_resourceObject



103
104
105
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 103

def reload_resource
  self.resource.reload if resource.respond_to?(:reload)
end

#resource_flash(status, resource, action, e: nil) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 88

def resource_flash(status, resource, action, e: nil)
  submit = commit_action(action)
  message = submit[status].respond_to?(:call) ? instance_exec(&submit[status]) : submit[status]

  return message.gsub('@resource', resource.to_s) if message.present?
  return nil if message.blank? && submit.key?(status)

  case status
  when :success then flash_success(resource, action)
  when :danger then flash_danger(resource, action, e: e)
  else
    raise "unknown resource flash status: #{status}"
  end
end

#save_resource(resource, action = :save, &block) ⇒ Object

This calls the appropriate member action, probably save!, on the resource.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 23

def save_resource(resource, action = :save, &block)
  save_action = ([:create, :update].include?(action) ? :save : action)
  raise "expected @#{resource_name} to respond to #{save_action}!" unless resource.respond_to?("#{save_action}!")

  if respond_to?(:current_user) && resource.respond_to?(:current_user=)
    resource.current_user ||= current_user
  end

  success = false
  exception = nil

  begin
    ActiveRecord::Base.transaction do
      EffectiveResources.transaction(resource) do
        run_callbacks(:resource_before_save)

        if resource.public_send("#{save_action}!") == false
          raise Effective::ActionFailed.new("failed to #{action}")
        end

        yield if block_given?

        run_callbacks(:resource_after_save)

        success = true
      rescue Effective::ActionFailed => e
        exception = e   # Dont rollback
      end
    end
  rescue ActiveRecord::RecordInvalid => e
    exception = e
  rescue => e
    exception = e
    notify_exception(e, resource, action) unless e.class.name == 'RuntimeError'
  end

  if exception.present?
    Rails.logger.info "  \e[31m\e[1mFAILED\e[0m\e[22m" # bold red
    Rails.logger.info "  Unable to #{action} #{resource} - #{exception.class} #{exception}"
    exception.backtrace.first(5).each { |line| Rails.logger.info('  ' + line) }

    if resource.respond_to?(:restore_attributes) && resource.persisted?
      resource.restore_attributes(['status', 'state'])
    end

    flash.now[:danger] = resource_flash(:danger, resource, action, e: exception)

    if exception.kind_of?(ActiveRecord::StaleObjectError)
      flash.now[:danger] = "#{flash.now[:danger]} <a href='#', class='alert-link' onclick='window.location.reload(true); return false;'>reload page and try again</a>"
    end
  end

  run_callbacks(success ? :resource_after_commit : :resource_error)

  success
end