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



96
97
98
99
100
101
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 96

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

#reload_resourceObject



91
92
93
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 91

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

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



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/controllers/concerns/effective/crud_controller/save.rb', line 76

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
# 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

  EffectiveResources.transaction(resource) do
    begin
      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 => e
      if Rails.env.development?
        Rails.logger.info "  \e[31m\e[1mFAILED\e[0m\e[22m" # bold red
        Rails.logger.info "  Unable to #{action} #{resource} - #{e.class} #{e}"
        e.backtrace.first(5).each { |line| Rails.logger.info('  ' + line) }
      end

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

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

      case e
      when 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>"
        raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
      when Effective::ActionFailed, ActiveRecord::RecordInvalid, RuntimeError
        raise(ActiveRecord::Rollback) # This is a soft error, we want to display the flash message to user
      else
        raise(e) # This is a real error that should be sent to 500. Client should not see the message.
      end
    end
  end

  run_callbacks(success ? :resource_after_commit : :resource_error)

  success
end