Singular Resource
Extracted from decent exposure, attempts to leave the useful parts, and just use helper_method
to expose your view models.
DOES
Allow you to find or initialize a simple resource, removing the boilerplate from CRUD actions.
DOES NOT
Expose the model in any way, scope the query to a collection method if defined, or deal with collections.
Use
It provides a private method that performs a query for the document when invoked, unless the id is not defined (new
, create
), in which case it returns an initialized model.
singular_resource :patient
Strategies
Like decent_exposure
, it's configurable, and provides different strategies.
By default, it uses StrongParametersStrategy
, which only assigns the attributes if a method name is provided via the attributes
option.
Options
:optional => "True if shouldn't fail if document does not exist",
:model => "Class or name of the model class",
:finder_parameter => "Name of the parameter that has the document's id",
:attributes => "Name of the attributes method name if using strong parameters",
:param_key => "Name of the parameter that has the document's attributes"
Comparison
What singular_resource
proposes is that you go from this:
class Controller
def new
@person = Person.new(params[:person])
end
def create
@person = Person.new(params[:person])
if @person.save
redirect_to(@person)
else
render :new
end
end
def edit
@person = Person.find(params[:id])
end
def update
@person = Person.find(params[:id])
if @person.update_attributes(params[:person])
redirect_to(@person)
else
render :edit
end
end
end
To something like this:
class Controller
expose(:person)
def create
if person.save
redirect_to(person)
else
render :new
end
end
def update
if person.save
redirect_to(person)
else
render :edit
end
end
end
With draper
If you use decorators, you can go from something like this:
class Controller
def new
@person = Person.new(params[:person]).decorate
end
def create
@person = Person.new(params[:person])
if @person.save
redirect_to(@person)
else
@person = @person.decorate
render :new
end
end
def edit
@person = Person.find(params[:id]).decorate
end
def update
@person = Person.find(params[:id])
if @person.update_attributes(params[:person])
redirect_to(@person)
else
@person = @person.decorate
render :edit
end
end
end
To something like this:
class Controller
before_filter :decorate_person
singular_resource(:person)
def create
if person.save
redirect_to(person)
else
render :new
end
end
def update
if person.save
redirect_to(person)
else
render :edit
end
end
private
def decorate_person
@person = person.decorate
end
end
If you think that the before_filter
is nasty or don't like ivars in your views, so do I! Check the present gem
Special Thanks
Singular Resource is a subset of decent_exposure.