I want to infer a decorator in a controller, so I generate a decorator the normal way (rails g decorator) and infer it in the controller. However, when I test with Postman, I get the error:
Could not infer a decorator for Employers::Job.
The error message shows that my syntax in the controller is incorrect (where .decorate is used), I don't know where I am going wrong.
I have tried changing the way of writing and specifying the decorator explicitly ( @job = Api::V2::Employers::JobDecorator.find(params[:id]).decorate), but again this gives a NoMethodError (undefined method `find' for Api::V2::Employers::JobDecorator:Class).
This is part of the controller:
class Api::V2::Employers::JobsController < Api::V2::Employers::BaseController
before_action :get_job, except: [:index, :create, :renew]
before_action :get_tags, only: [:create, :update]
before_action :get_address, only: :update
def show
@job = @employer.jobs.find(params[:id]).decorate
render json: @job
end
end
This is the decorator at the beginning:
class Api::V2::Employers::JobDecorator < Draper::Decorator
delegate_all
decorates_association :employer
def attributes
#somethings
end
end
UPDATE 2
Thanks to the suggestion in the comments, things changed after I used Api::V2::Employers::JobDecorator.decorate(@job) in the controller, but I got a new error. The message says undefined method 'attributes' for nil:NilClass, the source is a line of code from the following file:
#app/decorators/api/v2/employers/job_decorator.rb
class Api::V2::Employers::JobDecorator < Draper::Decorator
delegate_all
decorates_association :employer
def attributes
super.merge(
{
id: nil,
employer: nil,
}).delete_if { |k, v|
['class_name'].include?(k)
}
end
end
What is the reason for this?
CodePudding user response:
Draper infers the decorator from the object that is decorated and in your scenario is Employers::Job.
Because the decorator you want to be used has a totally different name, Api::V2::Employers::JobDecorator, you need to explicitly specify it.
So, Api::V2::Employers::JobDecorator.decorate(@job) is what you need.
More information, here
