Skip to content

Instantly share code, notes, and snippets.

@chienkira
Created December 29, 2020 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chienkira/b6cb119912b2a90abbe34e8c4240d691 to your computer and use it in GitHub Desktop.
Save chienkira/b6cb119912b2a90abbe34e8c4240d691 to your computer and use it in GitHub Desktop.
Metaprogramming when implement Rest API
module RestfulResponsable
extend ActiveSupport::Concern
included do
# ==== Callbacks ====
before_action :auto_set_resource, only: %i[show update destroy]
end
# ==== Below are 4 basic actions - CRUD of a restful api ====
# Use metaprogramming techniques to provide all shared functions!
def create
instance_variable_set("@#{resource_name}", resource_class.new(resource_params))
return error_422(resource_object.errors) unless resource_object.valid?
resource_object.save!
render :show, status: :created
end
def show
render :show, status: :ok
end
def update
resource_object.assign_attributes(resource_params)
return error_422(resource_object.errors) unless resource_object.valid?
resource_object.save!
render :show, status: :ok
end
def destroy
resource_object.destroy!
head :no_content
end
private
#
# The singular name for the resource class based on the controller
# Ex: cars_controller.rb will return "car" string
def resource_name
@resource_name ||= controller_name.singularize
end
#
# The resource class based on the controller
# Ex: cars_controller.rb will return "Car" class
def resource_class
@resource_class ||= resource_name.classify.constantize
end
#
# The controller for the resource must implement method "#{resource_name}_params" to
# limit permitted parameters for the individual model
# Ex: cars_controller.rb will return "car_params" method
def resource_params
@resource_params ||= send("#{resource_name}_params")
end
#
# Returns the resource from the created instance variable
# Ex: cars_controller.rb will return "@car" instance variable
def resource_object
instance_variable_get("@#{resource_name}")
end
#
# Use callbacks to share common setup or constraints between actions.
#
def auto_set_resource(resource = nil)app/controllers/concerns/restful_responsable.rb
resource ||= resource_class.find_by!(id: params[:id])
instance_variable_set("@#{resource_name}", resource)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment