Skip to content

Instantly share code, notes, and snippets.

@jonathanccalixto
Last active November 16, 2016 16:37
Show Gist options
  • Save jonathanccalixto/4f08769dcbaf45b9269fc5cc2cdbc140 to your computer and use it in GitHub Desktop.
Save jonathanccalixto/4f08769dcbaf45b9269fc5cc2cdbc140 to your computer and use it in GitHub Desktop.
Criando um FormFilter no rails
# Este aquivo fica em app/models/sponsor.rb
class Sponsor < ActiveRecord::Base
# aqui fica meu codigo e scopes
end
# Este cocdigo fica em app/controllers/members_controller.rb
class MembersController < ApplicationController
before_action :default_filters
# Estou usando a gem has_scope
has_scope :page, :default => 1
# GET /members
def index
authorize :sponsor # usando a gem pundit
respond_with collection
end
# aqui estão minhas actions, o que não vem ao caso mostrar agora
private
# Definindo os valores padrão para meus filtros
def default_filters
params[:filter] ||= {}
params[:filter][:document_status] = params[:filter].fetch(
:document_status,
(current_user.employee? ? DocumentStatusFilterValues::UNVERIFIED : DocumentStatusFilterValues::BOTH)
)
params[:filter][:card_photo] = params[:filter].fetch(
:card_photo,
BooleanFilterValues::BOTH
)
params[:filter][:proof_residence_photo] = params[:filter].fetch(
:proof_residence_photo,
BooleanFilterValues::BOTH
)
params[:filter][:identification_photo] = params[:filter].fetch(
:identification_photo,
BooleanFilterValues::BOTH
)
end
# Only allow a trusted parameter "white list" through.
def filter_params
return {} if params[:filter].blank?
params
.require( :filter )
.permit( policy(:member).permitted_filter_attributes )
end
def resource_class
@resource_class ||= Sponsor
end
helper_method :resource_class
def resource_name
@resource_name ||= :sponsor
end
helper_method :resource_name
def resource
@member ||= Sponsor.find(params[:id])
end
helper_method :resource
def filter
@filter ||= MemberFilter.new filter_params
end
helper_method :filter
def collection
@members ||= apply_scopes( filter.collection )
end
helper_method :collection
end
<%# Este aquivo se encontra em app/views/members/index.html.erb%>
<div class="panel panel-default">
<div class="panel-heading">
<h4><%= t "title.member.index" %></h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<%= simple_form_for filter, :url => members_path, :method => :get, :as => :filter do |f| %>
<div class="input-group" >
<%= f.text_field :search, :placeholder => t('placeholder.member.search'), :class => "form-control" %>
<span class="input-group-btn">
<button class="btn btn-success" title="Buscar" type="submit">
<i class="fa fa-search"></i>
</button>
</span>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h5><%= t "title.member.filter" %></h5>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<%= f.input :document_status, :collection => DocumentStatusFilterValues.to_a %>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<%= f.input :identification_photo, :collection => BooleanFilterValues.to_a %>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<%= f.input :proof_residence_photo, :collection => BooleanFilterValues.to_a %>
</div>
<div class="col-xs-3 col-sm-3 col-md-3 col-lg-3">
<%= f.input :card_photo, :collection => BooleanFilterValues.to_a %>
</div>
</div>
<div class="text-right">
<button class="btn btn-success" title="Buscar" type="submit">
<i class="fa fa-search"></i>
Filter
</button>
</div>
<% end %>
</div>
</div>
<hr/>
<div class="row">
<%- collection.each do |resource| %>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="panel panel-info">
<div class="panel-heading">
<h4><%= decore(resource).to_s %></h4>
</div>
<div class="panel-body">
<div class="row text-muted">
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
<strong class="font-16">
<%= decore(resource.user).human_attribute_name :nickname %>
</strong>
<br />
<%= decore(resource).nickname %>
</div>
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
<strong class="font-16">
<%= resource_class.human_attribute_name :email %>
</strong>
<br />
<%= decore(resource).email %>
</div>
</div>
<hr/>
<div class="row text-muted">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<strong>
<%= resource_class.human_attribute_name :created_at %>
</strong>
<br />
<%= decore(resource).created_at %>
</div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<strong>
<%= resource_class.human_attribute_name :updated_at %>
</strong>
<br />
<%= decore(resource).updated_at %>
</div>
</div>
</div>
<div class="panel-footer text-right" style="padding-bottom: 10px; padding-right: 10px;">
<%= link_to(member_path(resource), :class => "btn btn-sm btn-primary") do %>
<i class="fa fa-eye"></i>
<span><%= t "button.member.show" %></span>
<% end if policy(resource, :member).show? %>
<%= link_to(edit_member_path(resource), :class => "btn btn-sm btn-primary") do %>
<i class="fa fa-edit"></i>
<span><%= t "button.member.edit" %></span>
<% end if policy(resource, :member).edit? %>
<%= link_to(resource, :method => :delete, :data => { :confirm => t("messages.button.confirm.destroy") }, :class => "btn btn-sm btn-danger") do %>
<i class="fa fa-trash-o"></i>
<span><%= t "button.member.destroy" %></span>
<% end if policy(resource, :member).destroy? %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="panel-footer">
<%= paginate collection %>
</div>
</div>
# Este arquivo fica em lib/form_object.rb
module FormObject
class Base
extend EnumerateIt
include ActiveModel::Model
attr_accessor :created_at, :updated_at
class << self
def i18n_scope
:form_object
end
def decimal_attribute(*methods)
separator = I18n.t(:'number.format.separator')
delimiter = I18n.t(:'number.format.delimiter')
methods.each do |method|
define_method(:"#{method}=") do |value|
if value.to_s =~ %r(\A\d{1,3}(#{"\\#{delimiter}"}?\d{3})*#{"\\#{separator}"}\d+\z)
value = BigDecimal.new value.to_s.gsub(delimiter, '').gsub(separator, '.')
end
instance_variable_set "@#{method}", value
end
define_method(:"#{method}") do
instance_variable_get "@#{method}"
end
end
end
end
def attributes=(params)
params.each do |attr, value|
self.public_send("#{attr}=", value)
end if params
end
def created_at
@created_at ||= Time.current
end
def updated_at
@updated_at ||= Time.current
end
end
end
# Este aquivo está em app/form_objects/member_filter_form.rb
# Mesmo eu usando ele como um form_object, ele é também um query_object
class MemberFilter < FormObject::Base
attr_accessor :search, :card_photo, :proof_residence_photo
attr_accessor :identification_photo, :document_status
with_options :with => BooleanFilterValues do |o|
o.has_enumeration_for :card_photo, :create_helpers => { :prefix => true }
o.has_enumeration_for :identification_photo, :create_helpers => { :prefix => true }
o.has_enumeration_for :proof_residence_photo, :create_helpers => { :prefix => true }
end
has_enumeration_for :document_status, :with => DocumentStatusFilterValues,
:create_helpers => { :prefix => true }
def collection(force_reload = false)
@collection = nil if force_reload
@collection ||= begin
relation = Sponsor.ordered.search(self.search)
relation = self.document_status_scope(relation)
relation = self.card_photo_scope(relation)
relation = self.proof_residence_photo_scope(relation)
relation = self.identification_photo_scope(relation)
relation
end
end
def document_status_scope(relation)
case self.document_status
when DocumentStatusFilterValues::VERIFIED then
relation.verified
when DocumentStatusFilterValues::UNVERIFIED then
relation.unverified
when DocumentStatusFilterValues::REJECTED then
relation.rejected
else # DocumentStatusFilterValues::BOTH
relation
end
end
def card_photo_scope(relation)
case self.card_photo
when BooleanFilterValues::YES then
relation.with_card_photo
when BooleanFilterValues::NO then
relation.without_card_photo
else # BooleanFilterValues::BOTH
relation
end
end
def proof_residence_photo_scope(relation)
case self.proof_residence_photo
when BooleanFilterValues::YES then
relation.with_proof_residence_photo
when BooleanFilterValues::NO then
relation.without_proof_residence_photo
else # BooleanFilterValues::BOTH
relation
end
end
def identification_photo_scope(relation)
case self.identification_photo
when BooleanFilterValues::YES then
relation.with_identification_photo
when BooleanFilterValues::NO then
relation.without_identification_photo
else # BooleanFilterValues::BOTH
relation
end
end
end
#Este aquivoe está em app/enumerations/document_status_filter_values.rb
class DocumentStatusFilterValues < EnumerateIt::Base
associate_values :verified,
:unverified,
:rejected,
:both
end
#Este aquivoe está em app/enumerations/boolean_filter_values.rb
class BooleanFilterValues < EnumerateIt::Base
associate_values :yes,
:no,
:both
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment