lib/resourcelogic/parent.rb in resourcelogic-0.0.12 vs lib/resourcelogic/parent.rb in resourcelogic-0.9.0

- old
+ new

@@ -15,128 +15,160 @@ @belongs_to else @belongs_to[name.to_sym] = options end end - - def require_parent(value = nil) - rw_config(:require_parent, value, false) - end end module Urls + def self.included(klass) + klass.helper_method :new_parent_url, :new_parent_path, :edit_parent_url, :edit_parent_path, :parent_url, :parent_path, + :parent_collection_url, :parent_collection_path + end + private - def parent_url_parts(action = nil, url_params = {}) - [action] + contexts_url_parts + [url_params] + def new_parent_url(url_params = {}) + smart_url *([:new] + namespaces + [parent_url_options, url_params]) end - def parent_collection_url_parts(*args) - parent_url_parts(*args) + def new_parent_path(url_params = {}) + smart_path *([:new] + namespaces + [parent_url_options, url_params]) end + + def edit_parent_url(url_params = {}) + smart_url *([:edit] + namespaces + [parent_url_options, url_params]) + end + + def edit_parent_path(url_params = {}) + smart_path *([:edit] + namespaces + [parent_url_options, url_params]) + end + + def parent_url(url_params = {}) + smart_url *(namespaces + [parent_url_options, url_params]) + end + + def parent_path(url_params = {}) + smart_path *(namespaces + [parent_url_options, url_params]) + end + + def parent_collection_url(url_params = {}) + smart_url *(namespaces + [parent_model_name.to_s.pluralize.to_sym, url_params]) + end + + def parent_collection_path(url_params = {}) + smart_path *(namespaces + [parent_model_name.to_s.pluralize.to_sym, url_params]) + end + + def parent_url_options + if parent? + parent_name = (parent_alias || parent_model_name).to_sym + parent_singleton? ? parent_name : [parent_name, parent_object] + else + nil + end + end end module Reflection def self.included(klass) - klass.class_eval do - helper_method :parent?, :parent_model_name, :parent_object - before_filter :require_parent - end + klass.helper_method :parent?, :parent_model_name, :parent_object end private def belongs_to self.class.belongs_to end - - def parent_path_name - return @parent_path_name if defined?(@parent_path_name) - path_parts = request.path.split("/") - path_parts.reverse.each do |path_part| - next if path_part.blank? - if model_name_from_path_part(path_part) == parent_model_name - return @parent_path_name = path_part.to_sym - end - end - @parent_path_name = nil + + # Returns the relevant association proxy of the parent. (i.e. /posts/1/comments # => @post.comments) + # + def parent_association + @parent_association ||= parent_object.send(model_name.to_s.pluralize.to_sym) end - - def parent_route_name - return @parent_route_name if defined?(@parent_route_name) - path_parts = request.path.split("/") - path_parts.reverse.each do |path_part| - next if path_part.blank? - if model_name_from_path_part(path_part) == parent_model_name - return @parent_route_name = route_name_from_path_part(path_part) - end - end - @parent_route_name = parent_model_name + + def parent_alias + return @parent_alias if @parent_alias + parent_from_params? || parent_from_request? + @parent_alias end - + # Returns the type of the current parent # def parent_model_name - return @parent_model_name if defined?(@parent_model_name) - parent_from_path? + return @parent_model_name if @parent_model_name + parent_from_params? || parent_from_request? @parent_model_name end - - def parent_model - @parent_model ||= parent_model_name.to_s.camelize.constantize + + # Returns the type of the current parent extracted from params + # + def parent_from_params? + return @parent_from_params if defined?(@parent_from_params) + belongs_to.each do |model_name, options| + if !params["#{model_name}_id".to_sym].nil? + @parent_model_name = model_name + @parent_alias = options[:as] + return @parent_from_params = true + end + end + @parent_from_params = false end - + # Returns the type of the current parent extracted form a request path - # - def parent_from_path? - return @parent_from_path if defined?(@parent_from_path) + # + def parent_from_request? + return @parent_from_request if defined?(@parent_from_request) belongs_to.each do |model_name, options| - request.path.split('/').reverse.each do |path_part| - possible_model_names(model_name).each_with_index do |possible_name, index| - if [possible_name.to_s, possible_name.to_s.pluralize].include?(path_part) - @parent_model_name = model_name - return @parent_from_path = true - end - end + if request.path.split('/').include?((options[:as] && options[:as].to_s) || model_name.to_s) + @parent_model_name = model_name + @parent_alias = options[:as] + return @parent_from_request = true end end - @parent_from_path = false + @parent_from_request = false end - + # Returns true/false based on whether or not a parent is present. # def parent? !parent_model_name.nil? end - + # Returns true/false based on whether or not a parent is a singleton. - # + # def parent_singleton? - parent? && parent_id.nil? + !parent_from_params? end - + # Returns the current parent param, if there is a parent. (i.e. params[:post_id]) - def parent_id - params["#{parent_route_name}_id".to_sym] + def parent_param + params["#{parent_model_name}_id".to_sym] end - + + # Like the model method, but for a parent relationship. + # + def parent_model + @parent_model ||= parent_model_name.to_s.camelize.constantize + end + # Returns the current parent object if a parent object is present. # - def parent_object(reload = false) - return @parent_object if !reload && defined?(@parent_object) + def parent_object + return @parent_object if defined?(@parent_object) if parent? if parent_singleton? && respond_to?("current_#{parent_model_name}", true) @parent_object = send("current_#{parent_model_name}") - elsif parent_singleton? && parent_scope.respond_to?(parent_model_name) - @parent_object = parent_scope.send(parent_model_name, reload) else - @parent_object = parent_scope.find(parent_id) + @parent_object = parent_model.find(parent_param) end else @parent_object = nil end end - - def require_parent - raise StandardError.new("A parent is required to access this resource and no parent was found") if !parent? && self.class.require_parent == true + + # If there is a parent, returns the relevant association proxy. Otherwise returns model. + # + def end_of_association_chain + parent? ? parent_association : model end end end end \ No newline at end of file