Class: Avo::ResourceComponent

Inherits:
BaseComponent
  • Object
show all
Defined in:
app/components/avo/resource_component.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from BaseComponent

#has_with_trial

Instance Attribute Details

#fields_by_panelObject (readonly)

Returns the value of attribute fields_by_panel.



2
3
4
# File 'app/components/avo/resource_component.rb', line 2

def fields_by_panel
  @fields_by_panel
end

#has_as_belongs_to_many_panelsObject (readonly)

Returns the value of attribute has_as_belongs_to_many_panels.



5
6
7
# File 'app/components/avo/resource_component.rb', line 5

def has_as_belongs_to_many_panels
  @has_as_belongs_to_many_panels
end

#has_many_panelsObject (readonly)

Returns the value of attribute has_many_panels.



4
5
6
# File 'app/components/avo/resource_component.rb', line 4

def has_many_panels
  @has_many_panels
end

#has_one_panelsObject (readonly)

Returns the value of attribute has_one_panels.



3
4
5
# File 'app/components/avo/resource_component.rb', line 3

def has_one_panels
  @has_one_panels
end

#resourceObject (readonly)

Returns the value of attribute resource.



7
8
9
# File 'app/components/avo/resource_component.rb', line 7

def resource
  @resource
end

#resource_toolsObject (readonly)

Returns the value of attribute resource_tools.



6
7
8
# File 'app/components/avo/resource_component.rb', line 6

def resource_tools
  @resource_tools
end

#viewObject (readonly)

Returns the value of attribute view.



8
9
10
# File 'app/components/avo/resource_component.rb', line 8

def view
  @view
end

Instance Method Details

#authorize_association_for(policy_method) ⇒ Object

Ex: A Post has many Comments



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'app/components/avo/resource_component.rb', line 69

def authorize_association_for(policy_method)
  policy_result = true

  if @reflection.present?
    # Fetch the appropiate resource
    reflection_resource = field.resource
    # Fetch the record
    # Hydrate the resource with the record if we have one
    reflection_resource.hydrate(record: @parent_record) if @parent_record.present?
    # Use the related_name as the base of the association
    association_name = @reflection.name

    if association_name.present?
      method_name = "#{policy_method}_#{association_name}?".to_sym

      # Use the policy methods from the parent (Post)
      service = reflection_resource.authorization

      if service.has_method?(method_name, raise_exception: false)
        # Some policy methods should get the parent record in order to have the necessarry information to do the authorization
        # Example: Post->has_many->Comments
        #
        # When you want to authorize the creation/attaching of a Comment, you don't have the Comment instance.
        # But you do have the Post instance and you can get that in your policy to authorize against.
        parent_policy_methods = [:view, :create, :attach, :act_on]

        record = if parent_policy_methods.include?(policy_method)
          # Use the parent record (Post)
          reflection_resource.record
        else
          # Override the record with the child record (Comment)
          resource.record
        end
        policy_result = service.authorize_action(method_name, record: record, raise_exception: false)
      end
    end
  end

  policy_result
end

#can_create?Boolean

Returns:

  • (Boolean)


10
11
12
13
14
# File 'app/components/avo/resource_component.rb', line 10

def can_create?
  return authorize_association_for(:create) if @reflection.present?

  @resource.authorization.authorize_action(:create, raise_exception: false)
end

#can_delete?Boolean

Returns:

  • (Boolean)


16
17
18
19
20
# File 'app/components/avo/resource_component.rb', line 16

def can_delete?
  return authorize_association_for(:destroy) if @reflection.present?

  @resource.authorization.authorize_action(:destroy, raise_exception: false)
end

#can_detach?Boolean

Returns:

  • (Boolean)


22
23
24
25
26
27
28
29
30
31
# File 'app/components/avo/resource_component.rb', line 22

def can_detach?
  return false if @reflection.blank? || @resource.record.blank? || !authorize_association_for(:detach)

  # If the inverse_of is a belongs_to, we need to check if it's optional in order to know if we can detach it.
  if inverse_of.is_a?(ActiveRecord::Reflection::BelongsToReflection)
    inverse_of.options[:optional]
  else
    true
  end
end

#can_see_the_actions_button?Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
# File 'app/components/avo/resource_component.rb', line 47

def can_see_the_actions_button?
  return false if @actions.blank?

  return authorize_association_for(:act_on) if @reflection.present?

  @resource.authorization.authorize_action(:act_on, raise_exception: false) && !has_reflection_and_is_read_only
end

#can_see_the_destroy_button?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'app/components/avo/resource_component.rb', line 43

def can_see_the_destroy_button?
  @resource.authorization.authorize_action(:destroy, raise_exception: false)
end

#can_see_the_edit_button?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'app/components/avo/resource_component.rb', line 39

def can_see_the_edit_button?
  @resource.authorization.authorize_action(:edit, raise_exception: false)
end

#destroy_pathObject



55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/components/avo/resource_component.rb', line 55

def destroy_path
  args = {record: @resource.record, resource: @resource}

  args[:referrer] = if params[:via_resource_class].present?
    back_path
  # If we're deleting a resource from a parent resource, we need to go back to the parent resource page after the deletion
  elsif @parent_resource.present?
    helpers.resource_path(record: @parent_record, resource: @parent_resource)
  end

  helpers.resource_path(**args)
end

#detach_pathObject



33
34
35
36
37
# File 'app/components/avo/resource_component.rb', line 33

def detach_path
  return "/" if @reflection.blank?

  helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.record.to_param)
end

#has_reflection_and_is_read_onlyObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'app/components/avo/resource_component.rb', line 126

def has_reflection_and_is_read_only
  if @reflection.present? && @reflection.active_record.name && @reflection.name
    resource = Avo.resource_manager.get_resource_by_model_class(@reflection.active_record.name).new(params: helpers.params, view: view, user: helpers._current_user)
    fields = resource.get_field_definitions
    filtered_fields = fields.filter { |f| f.id == @reflection.name }
  else
    return false
  end

  if filtered_fields.present?
    filtered_fields.find { |f| f.id == @reflection.name }.is_disabled?
  else
    false
  end
end

#main_panelObject



110
111
112
113
114
# File 'app/components/avo/resource_component.rb', line 110

def main_panel
  @resource.get_items.find do |item|
    item.is_main_panel?
  end
end

#render_control(control) ⇒ Object



142
143
144
# File 'app/components/avo/resource_component.rb', line 142

def render_control(control)
  send "render_#{control.type}", control
end


116
117
118
119
120
# File 'app/components/avo/resource_component.rb', line 116

def sidebar
  return if Avo.license.lacks_with_trial(:resource_sidebar)

  @sidebar ||= search_for_sidebar
end


122
123
124
# File 'app/components/avo/resource_component.rb', line 122

def sidebar_component(form: nil)
  Avo::ResourceSidebarComponent.new resource: @resource, fields: sidebar.visible_items, params: params, view: view, form: form
end