ruby-on-railsadministrate

administrate gem deprecations on relations with class names


A model Transaction

belongs_to :consumer, class_name: 'User'

The administrate gem automatically picks up this relation and includes both the model relation and the id

ATTRIBUTE_TYPES = {
  user: Field::BelongsTo,
  consumer: Field::BelongsTo.with_options(class_name: "User"),
  consumer_id: Field::Number,

In an attempt to make the transaction searchable by the relation

  consumer: Field::BelongsTo.with_options(
    class_name: "User",
    searchable: true,
    searchable_fields: ['first_name', 'last_name', 'email', 'mobile']
  ),

There is an error complaining about user being nil

undefined method `+' for nil:NilClass

def display_resource(user)
  user ? user.last_name + ', ' + user.first_name : "No user provided"
end

which in the stack is invoking the user_dashboard. This error occurs also when using the auto-generated consumer: Field::BelongsTo.with_options(class_name: "User") definition of ATTRIBUTE_TYPES

user.nil is a misleading error, as:

> Transaction.where('consumer_id IS NULL').size
=> 0

the same occurs with user_id
If the class_name is removed, the error response is intuitively expected: uninitialized constant Consumer.

The documentation for customizing dashboards indicates for option setting:

:class_name (deprecated) - Specifies the name of the associated class.

but the resulting removal shows it is necessary. The consumer_id, if invoked in the collection of transactions, is shown properly.

How can this consumer be displayed?

administrate (0.14.0)
rails (6.0.3.6)


Solution

  • You have this code and this error:

    # The code
    def display_resource(user)
      user ? user.last_name + ', ' + user.first_name : "No user provided"
    end
    
    # The error
    # !> undefined method `+' for nil:NilClass
    

    The error is not about the user being nil. The error says that you are trying to apply + to nil, and you are not trying to apply + to the user: you are trying to apply it to user.last_name and user.first_name (as well as ", ").

    What is nil is one of these values that you expect 1) to be present, and 2) to be strings. A possible way for this to fail is if a user is missing a first name.

    Here's a way around that possibility:

    def display_resource(user)
      user ? [user.last_name, user.first_name].compact.join(", ") : "No user provided"
    end