Home > OS >  Rails Draper's Decorator caused ArgumentError
Rails Draper's Decorator caused ArgumentError

Time:12-15

I set up Draper's Decorator for a Rails project to replace the original helper. I moved the helper code to the Decorator:

def birthday(date)
  "MinYear#{date.year - 1911} Month#{date.month} Day#{date.day}"
end

And add .decorate text in View to use it

<%= user.decorate.birthday %>

However, this will cause an ArgumentError wrong number of arguments (given 0, expected 1)

def birthday(date)

If I remove the first date, it will appear a NoMethodError undefined method 'date' for #<UserDecorator:0x000055570cbafc58>

"MinYear#{date.year - 1911} Month#{date.month} Day#{date.day}"

How can I fix these errors?

CodePudding user response:

That ArgumentError is raised because you call birthday without passing in a date.
Doing <%= user.decorate.birthday(Date.current) %> will make the error go away.

But, this is probably not what you want since date is defined in the User model.

The easiest way to decorate something is to use delegate_all. It will make all methods from the User model available in the decorator.

class UserDecorator < Draper::Decorator
  delegate_all
  
  def birthday
   "MinYear#{date.year - 1911} Month#{date.month} Day#{date.day}"
  end
end

Note that any methods declared in the decorator will override those declared in the model, in your case birthday. For example, if you have other methods inside the decorator that call birthday, it will use the one from the decorator, not that from the model, which will be available by calling model.birthday.

Another approach is to call methods on the model object :

class UserDecorator < Draper::Decorator
  def date
    model.date
  end

  def birthday
   "MinYear#{date.year - 1911} Month#{date.month} Day#{date.day}"
  end
end
  • Related