class MagicResource::Container
Constants
- CONTEXT_PATTERNS
Attributes
changed[RW]
changed?[RW]
collection[RW]
context[R]
helper[RW]
item[RW]
name[RW]
resource[R]
resources[R]
rs[R]
Public Class Methods
_launch(helper, *args)
click to toggle source
# File lib/magic-resource/container.rb, line 171 def self._launch(helper, *args) args.present? ? self.new(args.first)._launch(helper, true) : # Let's try to keep resource_container to be private.. helper.send(:resource_container)._launch(helper) end
new(rs, context = nil)
click to toggle source
# File lib/magic-resource/container.rb, line 185 def initialize(rs, context = nil) rs = rs.object if rs.respond_to?(:object) self.rs, self.context = rs, context end
Private Class Methods
resource_name(duck)
click to toggle source
# File lib/magic-resource/container.rb, line 246 def self.resource_name(duck) raise 'Undefined resource name' if duck.nil? return duck if duck.kind_of?(Symbol) return duck.to_sym if duck.kind_of?(String) return duck.model_name.route_key.to_sym if duck.respond_to?(:model_name) return resource_name(duck.klass) if duck.respond_to?(:klass) return resource_name(duck.class) unless duck.kind_of?(Class) duck.name.underscore.pluralize.to_sym end
Public Instance Methods
_launch(helper, changed = false)
click to toggle source
# File lib/magic-resource/container.rb, line 165 def _launch(helper, changed = false) self.helper = helper self.changed = changed self end
content(index)
click to toggle source
# File lib/magic-resource/container.rb, line 154 def content(index) MagicResource.assert_restriction( :disable_content_for_helper, "`#content helper is too much magical...: #{index}" ) index = extract_context(index, :content) helper.resource_contents[rs].try(:[], index) end
content_for(index, *args, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 134 def content_for(index, *args, &block) MagicResource.assert_restriction( :disable_content_for_helper, "#content_for helper is too much magical...: #{index}" ) content = if block_given? raise ArgumentError.new("Both content param and block specified: #{index}") if args.present? helper.capture(&block) else raise ArgumentError.new("Need to specify the content by second param or block: #{index}") unless args.present? args.first end index = extract_context(index, :content) helper.resource_contents[rs] ||= {} helper.resource_contents[rs][index] = content end
context?(*args)
click to toggle source
# File lib/magic-resource/container.rb, line 20 def context?(*args) args.include?(context) end
form_for(action, *args, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 118 def form_for(action, *args, &block) options = args.extract_options! form_type = args.shift action, ct, route_args = extract_route_context(action) with_context(ct) do url, method = route_to(action, route_args) form_type ||= MagicResource.default_form_type form_type, obj = form_type.kind_of?(Ransack::Search) ? [:search, form_type] : [form_type, item] helper.public_send(:"#{form_type}_form_for", obj, {url: url, method: method}.merge(options), &block) end end
link_to(action, *args, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 68 def link_to(action, *args, &block) options = args.extract_options! action, ct, route_args = extract_route_context(action) with_context(ct) do url, method = route_to(action, route_args) link_options = {} link_options[:method] = method unless method == :get confirm = options.delete(:confirm){method === :delete} confirm = :confirm_destroy if confirm === true confirm = t(confirm) if confirm.kind_of?(Symbol) link_options[:data] = {confirm: confirm} if confirm label = label_for_link(action, args.first, &block) helper.link_to(label, url, link_options.deep_merge(options)) end end
link_to_if(condition, action, *args, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 102 def link_to_if(condition, action, *args, &block) if condition link_to(action, *args, &block) else action, ct = extract_route_context(action) args.extract_options! with_context(ct) do label_for_link(action, args.first, &block) end end end
link_to_unless(condition, *args, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 114 def link_to_unless(condition, *args, &block) link_to_if(!condition, *args, &block) end
path_to(action)
click to toggle source
Used in controller and view
# File lib/magic-resource/container.rb, line 90 def path_to(action) action, ct, route_args = extract_route_context(action) with_context(ct) do route_to(action, route_args).first end end
redirect_to(action, options = {})
click to toggle source
Used in controller
# File lib/magic-resource/container.rb, line 98 def redirect_to(action, options = {}) helper.redirect_to path_to(action), options end
render(partial, *args)
click to toggle source
# File lib/magic-resource/container.rb, line 24 def render(partial, *args) options = args.extract_options! if args.present? && form = args.shift raise 'Form object containing wrong resource' unless form.object == rs options[:f] = form unless options.has_key?(:f) end partial, ct = extract_context(partial, :template) lookup_templates = [name, :resources]. flat_map{|lc| ["#{lc}/#{ct}", lc] }. map{|l| "#{l}/#{partial}"} template = lookup_templates.find{|t| helper.lookup_context.template_exists?(t, [], true)} raise("Can't find #{lookup_templates[0]} template for #{name} resource") unless template with_context(ct){helper.with_resource_container(self){helper.render(template, options)}} end
render_collection(partial, options = {})
click to toggle source
# File lib/magic-resource/container.rb, line 43 def render_collection(partial, options = {}) partial, ct = extract_context(partial, :template) collection.map{|r| helper.r(r).render("#{name}::#{ct}/#{partial}", options)}.join.html_safe end
render_collection_build(partial, options = {})
click to toggle source
# File lib/magic-resource/container.rb, line 63 def render_collection_build(partial, options = {}) partial, ct = extract_context(partial, :template) helper.r(resources.soft_build).render("#{name}::#{ct}/#{partial}", options) end
t(key, options = {})
click to toggle source
# File lib/magic-resource/container.rb, line 48 def t(key, options = {}) key, ct = extract_context(key, :translation) lookup_keys = [name, :resources]. flat_map{|lc| ["#{lc}.#{ct}", lc] }. map{|l| :"#{l}.#{key}"} helper.t( lookup_keys[0], options.merge( default: lookup_keys[1..-1] + Array.wrap(options[:default]) ) ) end
Private Instance Methods
context=(new_context)
click to toggle source
# File lib/magic-resource/container.rb, line 203 def context=(new_context) @context = new_context || MagicResource.default_context end
extract_context(pattern, context_type)
click to toggle source
# File lib/magic-resource/container.rb, line 207 def extract_context(pattern, context_type) parse_params = CONTEXT_PATTERNS[context_type] pattern = pattern.to_s pattern.prepend(parse_params[:separator]) unless pattern.include?(parse_params[:separator]) pattern_parts = pattern.match(parse_params[:regexp]) raise("Wrong resource target pattern: #{pattern}") unless pattern_parts target_name = pattern_parts[:name].try(:to_sym) MagicResource.assert_restriction( :force_resource_name_definition, "Need to specify resource name when switching resource: #{pattern}" ) if changed? && target_name.nil? if target_name raise("Wrong resource name, expected #{name.inspect} but got #{target_name.inspect}") unless name == target_name end #Damn, string keys... pattern_parts.names.include?('context') ? [pattern_parts[:target].to_sym, pattern_parts[:context].try(:to_sym) || context] : pattern_parts[:target].to_sym end
extract_route_context(action)
click to toggle source
# File lib/magic-resource/container.rb, line 231 def extract_route_context(action) action, route_args = action.kind_of?(Hash) ? action.first : [action, {}] extract_context(action, :route) << route_args end
label_for_link(action, label, &block)
click to toggle source
# File lib/magic-resource/container.rb, line 277 def label_for_link(action, label, &block) if block_given? raise 'Both label and block are specified for link_to' if label return helper.capture(&block) end label ||= :"button_#{action}" label = t(label) if label.kind_of?(Symbol) label end
route_to(action, route_args = {}, only_path = true)
click to toggle source
# File lib/magic-resource/container.rb, line 256 def route_to(action, route_args = {}, only_path = true) action = (item.try(:persisted?) ? :update : :create) if action == :save options = helper.url_options.deep_merge( action: action, only_path: only_path, _recall: { controller: [name, context].compact.join('/'), # Need to confuse Rails.. action: 'hope_not_existing_action' } ).deep_merge(route_args) resource.try(:persisted?) ? options[:_recall][:id] = resource : options[:_recall].delete(:id) url = helper._routes.url_for(options) [url, url.http_verb] end
rs=(new_rs)
click to toggle source
# File lib/magic-resource/container.rb, line 190 def rs=(new_rs) @rs, self.name = new_rs.kind_of?(Symbol) ? [nil, new_rs] : [new_rs, nil] self.collection, self.item = rs.respond_to?(:to_ary) ? [rs, nil] : [nil, rs] # Just `||=` not working due to private method self.name = self.name || self.class.resource_name(rs) end
with_context(context) { || ... }
click to toggle source
# File lib/magic-resource/container.rb, line 237 def with_context(context) same_context = self.context == context old_context, self.context = self.context, context unless same_context yield ensure self.context = old_context unless same_context end