Module: RestfulJson::Controller::ClassMethods

Defined in:
lib/restful_json/controller.rb

Instance Method Summary collapse

Instance Method Details

#can_filter_by(*args) ⇒ Object

A whitelist of filters and definition of filter options related to request parameters.

If no options are provided or the :using option is provided, defines attributes that are queryable through the operation(s) already defined in can_filter_by_default_using, or can specify attributes:

can_filter_by :attr_name_1, :attr_name_2 # implied using: [eq] if RestfulJson.can_filter_by_default_using = [:eq] 
can_filter_by :attr_name_1, :attr_name_2, using: [:eq, :not_eq]

When :with_query is specified, it will call a supplied lambda. e.g. t is self.model_class.arel_table, q is self.model_class.all, and p is params:

can_filter_by :my_param_name, with_query: ->(t,q,p) {...}

When :through is specified, it will take the array supplied to through as 0 to many model names following by an attribute name. It will follow through each association until it gets to the attribute to filter by that via ARel joins, e.g. if the model Foobar has an association to :foo, and on the Foo model there is an assocation to :bar, and you want to filter by bar.name (foobar.foo.bar.name):

can_filter_by :my_param_name, through: [:foo, :bar, :name]


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/restful_json/controller.rb', line 73

def can_filter_by(*args)
  options = args.extract_options!

  # :using is the default action if no options are present
  if options[:using] || options.size == 0
    predicates = Array.wrap(options[:using] || self.can_filter_by_default_using)
    predicates.each do |predicate|
      predicate_sym = predicate.to_sym
      args.each do |attr|
        attr_sym = attr.to_sym
        self.param_to_attr_and_arel_predicate[attr_sym] = [attr_sym, :eq, options] if predicate_sym == :eq
        self.param_to_attr_and_arel_predicate["#{attr}#{self.predicate_prefix}#{predicate}".to_sym] = [attr_sym, predicate_sym, options]
      end
    end
  end

  if options[:with_query]
    args.each do |with_query_key|
      self.param_to_query[with_query_key.to_sym] = options[:with_query]
    end
  end

  if options[:through]
    args.each do |through_key|
      self.param_to_through[through_key.to_sym] = options[:through]
    end
  end
end

#includes_for(*args) ⇒ Object

Calls .includes(…) only on specified action queries. Take a hash of action as symbol to the includes, e.g.:

includes_for :create, are: [:category, :comments]
includes_for :index, :a_custom_action, are: [posts: [{comments: :guest}, :tags]]


120
121
122
123
124
125
126
127
128
129
# File 'lib/restful_json/controller.rb', line 120

def includes_for(*args)
  options = args.extract_options!
  args.each do |an_action|
    if options[:are]
      self.action_to_query_includes.merge!({an_action.to_sym => options[:are]})
    else
      raise "#{self.class.name} must supply an :are option with includes_for #{an_action.inspect}"
    end
  end
end

#including(*args) ⇒ Object

Calls .includes(…) on queries. Take a hash of action as symbol to the includes, e.g. to include(:category, :comments):

including :category, :comments

or includes([{comments: :guest, :tags]}):

including posts: [{comments: :guest}, :tags]


113
114
115
# File 'lib/restful_json/controller.rb', line 113

def including(*args)
  self.query_includes = args
end

#order_by(args) ⇒ Object

Takes an string, symbol, array, hash to indicate order. If not a hash, assumes is ascending. Is cumulative and order defines order of sorting, e.g:

#would order by foo_color attribute ascending
order_by :foo_color

or

order_by {:foo_date => :asc}, :foo_color, 'foo_name', {:bar_date => :desc}


155
156
157
# File 'lib/restful_json/controller.rb', line 155

def order_by(args)
  self.ordered_by = (Array.wrap(self.ordered_by) + Array.wrap(args)).flatten.compact.collect {|item|item.is_a?(Hash) ? item : {item.to_sym => :asc}}
end

#permit_action(*args) ⇒ Object

Use default or custom ActionController::Permitter with one or more actions, e.g.

permit_action :create, :update # this does nothing because it uses permitter_class, e.g. FooPermitter for FoosController

or:

permit_action :index, :some_custom_action, with: FoosQueryPermitter


182
183
184
185
186
187
188
189
190
# File 'lib/restful_json/controller.rb', line 182

def permit_action(*args)
  options = args.extract_options!
  args.each do |an_action|
    if options[:with]
      # if key set to nil, it will use the permitter_class method during the action
      self.action_to_permitter[an_action.to_sym] = options[:with]
    end
  end
end

#query_for(*args) ⇒ Object

Specify a custom query. If action specified does not have a method, it will alias_method index to create a new action method with that query.

t is self.model_class.arel_table and q is self.model_class.all, e.g.

query_for :index, is: -> {|t,q| q.where(:status_code => 'green')}


135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/restful_json/controller.rb', line 135

def query_for(*args)
  options = args.extract_options!
  # TODO: support custom actions to be automaticaly defined
  args.each do |an_action|
    if options[:is]
      self.action_to_query[an_action.to_sym] = options[:is]
    else
      raise "#{self.class.name} must supply an :is option with query_for #{an_action.inspect}"
    end
    unless an_action.to_sym == :index
      alias_method an_action.to_sym, :index
    end
  end
end

#serialize_action(*args) ⇒ Object

Associate a non-standard ActiveModel::Serializer for one or more actions, e.g.

serialize_action :index, with: FoosSerializer

or

serialize_action :index, :some_custom_action, with: FooSerializer

The default functionality of each action is to use serialize for show, each, create, update, and destroy and serialize_each for index and any custom actions created with query_for. To override that, specify the :for option with value as :array or :each:

serialize_action :index, :some_custom_action, with: FoosSerializer, for: :array


166
167
168
169
170
171
172
173
174
175
176
# File 'lib/restful_json/controller.rb', line 166

def serialize_action(*args)
  options = args.extract_options!
  args.each do |an_action|
    if options[:with]
      self.action_to_render_options[an_action.to_sym] ||= {}
      self.action_to_render_options[an_action.to_sym]["restful_json_serialization_#{options[:for] && options[:for].to_sym == :array ? 'array' : 'default'}".to_sym] = options[:with]
    else
      raise "#{self.class.name} must supply an :with option with serialize_action #{an_action.inspect}"
    end
  end
end

#supports_functions(*args) ⇒ Object

Can specify additional functions in the index, e.g.

supports_functions :skip, :uniq, :take, :count


104
105
106
107
# File 'lib/restful_json/controller.rb', line 104

def supports_functions(*args)
  args.extract_options! # remove hash from array- we're not using it yet
  self.supported_functions += args
end