Skip to content

Instantly share code, notes, and snippets.

@Guri-ksolves
Last active August 31, 2017 07:24
Show Gist options
  • Save Guri-ksolves/edc1ac14547dd926bba85703219b8ff6 to your computer and use it in GitHub Desktop.
Save Guri-ksolves/edc1ac14547dd926bba85703219b8ff6 to your computer and use it in GitHub Desktop.
Usefull ruby patch (Inherited resources)
#Inherited Resources speeds up development by making your controllers inherit all restful actions so you just
#have to focus on what is important.
#It makes your controllers more powerful and cleaner at the same time.
#In addition to making your controllers follow a pattern,
#it helps you to write better code by following fat models and skinny controllers convention.
#There are two screencasts available besides this README:
gem 'inherited_resources'
$ gem install has_scope
$ gem install responders
#Using responders will set the flash message to :notice and :alert. You can change that through the following configuration value:
InheritedResources.flash_keys = [ :success, :failure ]
class ProjectsController < InheritedResources::Base
actions :index, :show, :new, :create
end
#Or:
class ProjectsController < InheritedResources::Base
actions :all, :except => [ :edit, :update, :destroy ]
end
#In your views, you will get the following helpers:
resource #=> @project
collection #=> @projects
resource_class #=> Project
#If for some reason you cannot inherit from InheritedResources::Base, you can call inherit_resources in your controller class scope:
class AccountsController < ApplicationController
inherit_resources
end
#One reason to use the inherit_resources macro would be to ensure that your controller never responds with the html mime-type.
#InheritedResources::Base already responds to :html, and the respond_to macro is strictly additive. Therefore, if you want to create a controller that,
#for example, responds ONLY via :js, you will have to write it this way:
class AccountsController < ApplicationController
respond_to :js
inherit_resources
end
#Overwriting defaults
#Whenever you inherit from InheritedResources, several defaults are assumed.
# For example you can have an AccountsController for account management while the resource is a User:
class AccountsController < InheritedResources::Base
defaults :resource_class => User, :collection_name => 'users', :instance_name => 'user'
end
#Overwriting actions
#Let's suppose that after destroying a project you want to redirect to your root url instead of redirecting to projects url.
# You just have to do:
class ProjectsController < InheritedResources::Base
def destroy
super do |format|
format.html { redirect_to root_url }
end
end
end
# Or for shortcut
class ProjectsController < InheritedResources::Base
def destroy
destroy! { root_url }
end
end
# If you simply want to change the flash message for a particular action, you can pass the message to the parent action using the keys :notice and :alert (as you would with flash):
class ProjectsController < InheritedResources::Base
def create
create!(:notice => "Dude! Nice job creating that project.")
end
end
#Now let's suppose that before create a project you have to do something special but you don't want to create a before filter for it:
class ProjectsController < InheritedResources::Base
def create
@project = Project.new(params[:project])
@project.something_special!
create!
end
end
#Yes, it's that simple! The nice part is since you already set the instance variable @project, it will not build a project again.
#Same goes for updating the project:
class ProjectsController < InheritedResources::Base
def update
@project = Project.find(params[:id])
@project.something_special!
update!
end
end
#Before we finish this topic, we should talk about one more thing: "success/failure blocks".
#Let's suppose that when we update our project, in case of failure,
#we want to redirect to the project url instead of re-rendering the edit template.
class ProjectsController < InheritedResources::Base
def update
update! do |success, failure|
failure.html { redirect_to project_url(@project) }
end
end
end
#Much better! So explaining everything: when you give a block which expects one argument it will be executed in
#both scenarios: success and failure.
# But if you give a block that expects two arguments, the first will be executed only in success scenarios
# and the second in failure scenarios.
#You keep everything clean and organized inside the same action.
#Success and failure scenarios on destroy
#The destroy action can also fail, this usually happens when you have a before_destroy callback in your model which returns false. However, in order to tell InheritedResources that it really failed, you need to add errors to your model. So your before_destroy callback on the model should be something like this:
def before_destroy
if cant_be_destroyed?
errors.add(:base, "not allowed")
false
end
end
#for more info go to
#https://github.com/activeadmin/inherited_resources
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment