administrate icon indicating copy to clipboard operation
administrate copied to clipboard

"The option :class_name is deprecated." but I think it is still needed.

Open gregmatthewcrossley opened this issue 2 years ago • 4 comments

  • What were you trying to do? I am defining some ATTRIBUTE_TYPES in a dashboard. One of my attributes (lead_practitioners) is a belongs_to relation where its class name doesn't match the relation name. My model defines this belongs_to relation like so:
class Practice < ApplicationRecord
  has_many :practitioner_practices, inverse_of: :practice, dependent: :destroy
  has_many :practitioners, through: :practitioner_practices
  has_many :lead_practitioners, -> { where(practitioner_practices: {lead: true}) }, through: :practitioner_practices, source: :practitioner
  ...
  • What did you end up with (logs, or, even better, example apps are great!)? I am using the class_name option when I define the attribute in the dashboard file, like this:
ATTRIBUTE_TYPES = {
   ...
    lead_practitioner: Field::BelongsTo.with_options(class_name: "Practitioner"),
    ...
 }

which works, but warns me with this:

DEPRECATION WARNING: The option :class_name is deprecated. Administrate should detect it automatically. Please file an issue at https://github.com/thoughtbot/administrate/issues if you think otherwise.

If I remove the class_name option and let the Administrate gem try to determine the class name on its own, I get this error:

ActionView::Template::Error:
       undefined method `klass' for nil:NilClass
     
               reflection(resource_class, attr).klass

Even if I explicitly add the class name to the model relation, like so:

  has_many :lead_practitioners, -> { where(practitioner_practices: {lead: true}) }, through: :practitioner_practices, source: :practitioner, class_name: "Practitioner"

I get the same error as above.

  • What versions are you running?
    • Rails: 7.0.4
    • administrate: 0.18.0

gregmatthewcrossley avatar May 24 '23 13:05 gregmatthewcrossley

@jamie, I think this depreciation warning is from your commit. Just wondering if you agree with my assessment here.

gregmatthewcrossley avatar May 24 '23 19:05 gregmatthewcrossley

You're seeing warn_of_deprecated_option, not method - probably coming from https://github.com/thoughtbot/administrate/blob/44ad6ce1072fbd897f1faaf7231b3b5a0b92f535/lib/administrate/field/associative.rb#L40. You may want to try resource_class rather than class_name.

jamie avatar May 24 '23 19:05 jamie

Thank you for letting us know of this use case. We'll look into it. Ultimately, we want Administrate to be able to detect all these cases correctly so that we can remove the :class_name option for good.

For now, use what works for you. If you do need :class_name, you can silence the deprecation warning by overriding the method Administrate.warn_of_deprecated_option. For example like so:

module Administrate
  def self.warn_of_deprecated_option(_)
    # method override to temporarily silence warning
  end
end

Then when administrate is correctly detecting this case, you can remove the code above and your usage of :class_name.

Having said that... it's possible that this is fixed already in master. Would you be able to check? To do this, reference Administrate in your gemfile like so:

gem "administrate", git: "https://github.com/thoughtbot/administrate"

Does that solve your problem?

pablobm avatar May 26 '23 15:05 pablobm

I am also running into an issue where this option is still needed. We have this STI set up:

class Import < ApplicationRecord
  has_many :data_imports, inverse_of: "import" # ideally this would go on Imports::Pdf but it has to be at the top-level due to another Administrate issue
module Imports
  class Pdf < Import
module Imports
  class Doc < Import
class DataImport < ApplicationRecord
  belongs_to :import, class_name: "Imports::Pdf", foreign_key: :import_id, optional: true
class DataImportDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    ...
    import: Field::BelongsTo

Without the class_name I get an uninitialized constant Imports::PdfDashboard error. With the class_name: "Import" it works fine. I can get around not having the class_name option if I set my belongs_to in the DataImport model to the top-level import record like so:

belongs_to :import, foreign_key: :import_id, optional: true

but as a DataImport record can only ever be attached to type Imports::Pdf I would prefer to leave that as-is.

littleforest avatar May 08 '24 20:05 littleforest