1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 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 101 102 103 104 105 106 107 108 109 110 111 112
|
module InheritedResources
# = belongs_to
#
# Let's suppose that we have some tasks that belongs to projects. To specify
# this assoication in your controllers, just do:
#
# class TasksController < InheritedResources::Base
# belongs_to :project
# end
#
# belongs_to accepts several options to be able to configure the association.
# For example, if you want urls like /projects/:project_title/tasks, you
# can customize how InheritedResources find your projects:
#
# class TasksController < InheritedResources::Base
# belongs_to :project, :finder => :find_by_title!, :param => :project_title
# end
#
# It also accepts :route_name, :parent_class and :instance_name as options.
# Check the lib/inherited_resources/class_methods.rb for more.
#
# = nested_belongs_to
#
# Now, our Tasks get some Comments and you need to nest even deeper. Good
# practices says that you should never nest more than two resources, but sometimes
# you have to for security reasons. So this is an example of how you can do it:
#
# class CommentsController < InheritedResources::Base
# nested_belongs_to :project, :task
# end
#
# If you need to configure any of these belongs to, you can nested them using blocks:
#
# class CommentsController < InheritedResources::Base
# belongs_to :project, :finder => :find_by_title!, :param => :project_title do
# belongs_to :task
# end
# end
#
# Warning: calling several belongs_to is the same as nesting them:
#
# class CommentsController < InheritedResources::Base
# belongs_to :project
# belongs_to :task
# end
#
# In other words, the code above is the same as calling nested_belongs_to.
#
module BelongsToHelpers
protected
# Parent is always true when belongs_to is called.
#
def parent?
true
end
def parent
@parent ||= association_chain[-1]
end
def parent_type
parent.class.name.underscore.to_sym
end
private
# Evaluate the parent given. This is used to nest parents in the
# association chain.
#
def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
get_parent_ivar(parent_config[:instance_name]) ||
set_parent_instance(parent_config, chain)
end
def get_parent_ivar(instance_name) #:nodoc:
instance_variable_defined?(:"@#{instance_name}") &&
instance_variable_get("@#{instance_name}")
end
def set_parent_instance(parent_config, chain) #:nodoc:
if parent_config[:singleton]
parent = if chain
chain.send(parent_config[:instance_name])
else
nil
end
else
parent = if chain
chain.send(parent_config[:collection_name])
else
parent_config[:parent_class]
end
parent = parent.send(parent_config[:finder], params[parent_config[:param]])
end
instance_variable_set("@#{parent_config[:instance_name]}", parent)
end
# Maps parents_symbols to build association chain. In this case, it
# simply return the parent_symbols, however on polymorphic belongs to,
# it has some customization.
#
def symbols_for_association_chain #:nodoc:
parents_symbols
end
end
end
|