• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gregschmit / rails-rest-framework / 22598997607

02 Mar 2026 10:38PM UTC coverage: 90.592% (+0.6%) from 90.008%
22598997607

push

github

gregschmit
Update gems, fix Rails 8.1 issues.

1117 of 1233 relevant lines covered (90.59%)

221.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.31
/lib/rest_framework.rb
1
# frozen_string_literal: true
2

3
module RESTFramework
2✔
4
  BUILTIN_ACTIONS = {
2✔
5
    index: :get,
6
    new: :get,
7
    create: :post,
8
  }.freeze
9
  BUILTIN_MEMBER_ACTIONS = {
10
    show: :get,
2✔
11
    edit: :get,
12
    update: [ :put, :patch ].freeze,
13
    destroy: :delete,
14
  }.freeze
15
  RRF_BUILTIN_ACTIONS = {
2✔
16
    options: :options,
17
  }.freeze
18
  RRF_BUILTIN_BULK_ACTIONS = {
19
    update_all: [ :put, :patch ].freeze,
2✔
20
    destroy_all: :delete,
21
  }.freeze
22

23
  # Storage for extra routes and associated metadata.
24
  EXTRA_ACTION_ROUTES = Set.new
2✔
25
  ROUTE_METADATA = {}
2✔
26

27
  # We put most vendored external assets into these files to make precompilation and serving faster.
28
  EXTERNAL_CSS_NAME = "rest_framework/external.min.css"
2✔
29
  EXTERNAL_JS_NAME = "rest_framework/external.min.js"
2✔
30

31
  # We should always add the `.min` extension prefix even if the assets are not minified, to avoid
32
  # sprockets minifying the assets. We target propshaft, so we want these assets to just be passed
33
  # through.
34
  # rubocop:disable Layout/LineLength
35
  EXTERNAL_ASSETS = {
36
    # Bootstrap
37
    "bootstrap.min.css" => {
2✔
38
      url: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css",
39
      sri: "sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr",
40
    },
41
    "bootstrap.min.js" => {
42
      url: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.bundle.min.js",
43
      sri: "sha384-ndDqU0Gzau9qJ1lfW4pNLlhNTkCfHzAVBReH9diLvGRem5+R9g2FzA8ZGN954O5Q",
44
    },
45

46
    # Bootstrap Icons
47
    "bootstrap-icons.min.css" => {
48
      url: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css",
49
      inline_fonts: true,
50
    },
51

52
    # Highlight.js
53
    "highlight.min.js" => {
54
      url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/highlight.min.js",
55
      sri: "sha512-6QBAC6Sxc4IF04SvIg0k78l5rP5YgVjmHX2NeArelbxM3JGj4imMqfNzEta3n+mi7iG3nupdLnl3QrbfjdXyTg==",
56
    },
57
    "highlight-json.min.js" => {
58
      url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/languages/json.min.js",
59
      sri: "sha512-8JO7/pRnd1Ce8OBXWQg85e5wNPJdBaQdN8w4oDa+HelMXaLwCxTdbzdWHmJtWR9AmcI6dOln4FS5/KrzpxqqfQ==",
60
    },
61
    "highlight-xml.min.js" => {
62
      url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/languages/xml.min.js",
63
      sri: "sha512-/vq6wbS2Qkv8Hj4mP3Jd/m6MbnIrquzZiUt9tIluQfe332IQeFDrSIK7j2cjAyn6/9Ntb2WMPbo1CAxu26NViA==",
64
    },
65
    "highlight-a11y-dark.min.css" => {
66
      url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/a11y-dark.min.css",
67
      sri: "sha512-Vj6gPCk8EZlqnoveEyuGyYaWZ1+jyjMPg8g4shwyyNlRQl6d3L9At02ZHQr5K6s5duZl/+YKMnM3/8pDhoUphg==",
68
      extra_tag_attrs: { class: "rrf-dark-mode" },
69
    },
70
    "highlight-a11y-light.min.css" => {
71
      url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/a11y-light.min.css",
72
      sri: "sha512-WDk6RzwygsN9KecRHAfm9HTN87LQjqdygDmkHSJxVkVI7ErCZ8ZWxP6T8RvBujY1n2/E4Ac+bn2ChXnp5rnnHA==",
73
      extra_tag_attrs: { class: "rrf-light-mode" },
74
    },
75

76
    # NeatJSON
77
    "neatjson.min.js" => {
78
      url: "https://cdn.jsdelivr.net/npm/neatjson@0.10.6/javascript/neatjson.min.js",
79
      exclude_from_docs: true,
80
    },
81

82
    # Trix
83
    "trix.min.css" => {
84
      url: "https://unpkg.com/trix@2.0.8/dist/trix.css",
85
      exclude_from_docs: true,
86
    },
87
    "trix.min.js" => {
88
      url: "https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js",
89
      exclude_from_docs: true,
90
    },
91
  }.map { |name, cfg|
92
    ext = File.extname(name)
22✔
93
    if ext == ".js"
22✔
94
      cfg[:place] = "javascripts"
12✔
95
      cfg[:extra_tag_attrs] ||= {}
12✔
96
      cfg[:tag_attrs] = {
12✔
97
        src: cfg[:url],
98
        integrity: cfg[:sri],
99
        crossorigin: "anonymous",
100
        referrerpolicy: "no-referrer",
101
        defer: true,
102
        **cfg[:extra_tag_attrs],
103
      }
104
      cfg[:tag] = ActionController::Base.helpers.tag.script(**cfg[:tag_attrs])
12✔
105
    elsif ext == ".css"
10✔
106
      cfg[:place] = "stylesheets"
10✔
107
      cfg[:extra_tag_attrs] ||= {}
10✔
108
      cfg[:tag_attrs] = {
10✔
109
        rel: "stylesheet",
110
        href: cfg[:url],
111
        integrity: cfg[:sri],
112
        crossorigin: "anonymous",
113
        **cfg[:extra_tag_attrs],
114
      }
115
      cfg[:tag] = ActionController::Base.helpers.tag.link(**cfg[:tag_attrs])
10✔
116
    else
117
      raise "Unknown asset extension: #{ext}."
×
118
    end
119

120
    [ name, cfg ]
22✔
121
  }.to_h.freeze
122
  # rubocop:enable Layout/LineLength
123

124
  EXTERNAL_UNSUMMARIZED_ASSETS = EXTERNAL_ASSETS.select { |_, cfg| cfg[:extra_tag_attrs].present? }
24✔
125

126
  # Global configuration should be kept minimal, as controller-level configurations allows multiple
127
  # APIs to be defined to behave differently.
128
  class Config
2✔
129
    DEFAULT_LABEL_FIELDS = %w[name label login title email username url].freeze
2✔
130
    DEFAULT_SEARCH_COLUMNS = DEFAULT_LABEL_FIELDS + %w[description note].freeze
2✔
131
    DEFAULT_READ_ONLY_FIELDS = %w[
2✔
132
      created_at
133
      created_by
134
      created_by_id
135
      updated_at
136
      updated_by
137
      updated_by_id
138
      _method
139
      utf8
140
      authenticity_token
141
    ].freeze
142
    DEFAULT_WRITE_ONLY_FIELDS = %w[
2✔
143
      password
144
      password_confirmation
145
    ].freeze
146

147
    # Permits use of `render(api: obj)` syntax over `render_api(obj)`; `true` by default.
148
    attr_accessor :register_api_renderer
2✔
149

150
    # Run `rrf_finalize` on controllers automatically using a `TracePoint` hook. This is `true` by
151
    # default, and can be disabled for performance, and must be global because we have to determine
152
    # this before any controller-specific configuration is set. If this is set to `false`, then you
153
    # must manually call `rrf_finalize` after any configuration on each controller that needs to
154
    # participate in:
155
    #  - Model delegation, for the helper methods to be defined dynamically.
156
    #  - Websockets, for `::Channel` class to be defined dynamically.
157
    #  - Controller configuration freezing.
158
    attr_accessor :auto_finalize
2✔
159

160
    # Freeze configuration attributes during finalization to prevent accidental mutation.
161
    attr_accessor :freeze_config
2✔
162

163
    # Specify reverse association tables that are typically very large, and therefore should not be
164
    # added to fields by default.
165
    attr_accessor :large_reverse_association_tables
2✔
166

167
    # Whether the backtrace should be shown in rescued errors.
168
    attr_accessor :show_backtrace
2✔
169

170
    # Disable `rescue_from` on the controller mixins.
171
    attr_accessor :disable_rescue_from
2✔
172

173
    # The default label fields to use when generating labels for `has_many` associations.
174
    attr_accessor :label_fields
2✔
175

176
    # The default search columns to use when generating search filters.
177
    attr_accessor :search_columns
2✔
178

179
    # Helper to set global read/write only fields.
180
    attr_accessor :read_only_fields
2✔
181
    attr_accessor :write_only_fields
2✔
182

183
    # Option to use vendored assets (requires sprockets or propshaft) rather than linking to
184
    # external assets (the default).
185
    attr_accessor :use_vendored_assets
2✔
186

187
    def initialize
2✔
188
      self.register_api_renderer = true
2✔
189
      self.auto_finalize = true
2✔
190

191
      self.show_backtrace = Rails.env.development?
2✔
192

193
      self.label_fields = DEFAULT_LABEL_FIELDS
2✔
194
      self.search_columns = DEFAULT_SEARCH_COLUMNS
2✔
195
      self.read_only_fields = DEFAULT_READ_ONLY_FIELDS
2✔
196
      self.write_only_fields = DEFAULT_WRITE_ONLY_FIELDS
2✔
197
    end
198
  end
199

200
  def self.config
2✔
201
    @config ||= Config.new
1,716✔
202
  end
203

204
  def self.configure
2✔
205
    yield(self.config)
×
206
  end
207

208
  def self.features
2✔
209
    @features ||= {}
×
210
  end
211
end
212

213
require_relative "rest_framework/engine"
2✔
214
require_relative "rest_framework/errors"
2✔
215
require_relative "rest_framework/filters"
2✔
216
require_relative "rest_framework/generators"
2✔
217
require_relative "rest_framework/mixins"
2✔
218
require_relative "rest_framework/paginators"
2✔
219
require_relative "rest_framework/routers"
2✔
220
require_relative "rest_framework/serializers"
2✔
221
require_relative "rest_framework/utils"
2✔
222
require_relative "rest_framework/version"
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc