instance method
edit_polymorphic_path
Ruby on Rails edge
Since edgeSignature
edit_polymorphic_path(record_or_hash, options = {})
No documentation comment.
Parameters
-
record_or_hashreq -
optionsopt = {}
Source
# File actionpack/lib/action_dispatch/routing/polymorphic_routes.rb, line 164
def edit_polymorphic_path(record_or_hash, options = {}) = polymorphic_path_for_action("edit", record_or_hash, options)
def new_polymorphic_url(record_or_hash, options = {}) = polymorphic_url_for_action("new", record_or_hash, options)
def new_polymorphic_path(record_or_hash, options = {}) = polymorphic_path_for_action("new", record_or_hash, options)
private
def polymorphic_url_for_action(action, record_or_hash, options)
if options.empty? && !(Hash === record_or_hash) && !polymorphic_mapping(record_or_hash)
# What polymorphic_url does with action: as the only option.
HelperMethodBuilder.polymorphic_method(self, record_or_hash, action, :url, options)
else
polymorphic_url(record_or_hash, options.merge(action: action))
end
end
def polymorphic_path_for_action(action, record_or_hash, options)
if options.empty? && !(Hash === record_or_hash) && !polymorphic_mapping(record_or_hash)
# What polymorphic_path does with action: as the only option.
HelperMethodBuilder.polymorphic_method(self, record_or_hash, action, :path, options)
else
polymorphic_path(record_or_hash, options.merge(action: action))
end
end
def polymorphic_mapping(record)
if record.respond_to?(:to_model)
_routes.polymorphic_mappings[record.to_model.model_name.name]
else
_routes.polymorphic_mappings[record.class.name]
end
end
class HelperMethodBuilder # :nodoc:
CACHE = { path: {}, url: {} }.freeze
def self.get(action, type)
type = type.to_sym
CACHE[type].fetch(action) { build action, type }
end
def self.url; CACHE[:url][nil]; end
def self.path; CACHE[:path][nil]; end
def self.build(action, type)
prefix = action ? "#{action}_" : ""
suffix = type
if action.to_s == "new"
HelperMethodBuilder.singular prefix, suffix
else
HelperMethodBuilder.plural prefix, suffix
end
end
def self.singular(prefix, suffix)
new(->(name) { name.singular_route_key }, prefix, suffix)
end
def self.plural(prefix, suffix)
new(->(name) { name.route_key }, prefix, suffix)
end
def self.polymorphic_method(recipient, record_or_hash_or_array, action, type, options)
builder = get action, type
case record_or_hash_or_array
when Array
record_or_hash_or_array = record_or_hash_or_array.compact
if record_or_hash_or_array.empty?
raise ArgumentError, "Nil location provided. Can't build URI."
end
if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
recipient = record_or_hash_or_array.shift
end
method, args = builder.handle_list record_or_hash_or_array
when String, Symbol
method, args = builder.handle_string record_or_hash_or_array
when Class
method, args = builder.handle_class record_or_hash_or_array
when nil
raise ArgumentError, "Nil location provided. Can't build URI."
else
return builder.dispatch_model(recipient, record_or_hash_or_array, options.empty? ? nil : options)
end
if options.empty?
recipient.public_send(method, *args)
else
recipient.public_send(method, *args, options)
end
end
attr_reader :suffix, :prefix
def initialize(key_strategy, prefix, suffix)
@key_strategy = key_strategy
@prefix = prefix
@suffix = suffix
@method_names_key = :"action_dispatch_polymorphic_#{prefix}#{suffix}_method_names"
end
def handle_string(record)
[get_method_for_string(record), []]
end
def handle_string_call(target, str)
target.public_send get_method_for_string str
end
def handle_class(klass)
[get_method_for_class(klass), []]
end
def handle_class_call(target, klass)
target.public_send get_method_for_class klass
end
def handle_model_call(target, record)
if mapping = polymorphic_mapping(target, record)
mapping.call(target, [record], suffix == "path")
else
dispatch_model(target, record)
end
end
# Calls the named route helper for a model straight away, rather
# than building an argument list and a pair for the caller to splat
# apart again.
def dispatch_model(target, record, options = nil)
model = record.to_model
if model.persisted?
method = get_method_for_string(model.model_name.singular_route_key)
options ? target.public_send(method, model, options) : target.public_send(method, model)
else
method = get_method_for_class(model)
options ? target.public_send(method, options) : target.public_send(method)
end
end
# Takes ownership of +list+, a copy made by the caller.
def handle_list(list)
record = list.pop
args = []
named_route = prefix.dup
list.each do |parent|
named_route <<
case parent
when Symbol
parent.name
when String
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
when Class
args << parent
parent.model_name.singular_route_key
else
args << parent.to_model
parent.to_model.model_name.singular_route_key
end
named_route << "_"
end
named_route <<
case record
when Symbol
record.name
when String
raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
when Class
@key_strategy.call record.model_name
else
model = record.to_model
if model.persisted?
args << model
model.model_name.singular_route_key
else
@key_strategy.call model.model_name
end
end
named_route << "_" << suffix.to_s
[named_route, args]
end
private
def polymorphic_mapping(target, record)
if record.respond_to?(:to_model)
target._routes.polymorphic_mappings[record.to_model.model_name.name]
else
target._routes.polymorphic_mappings[record.class.name]
end
end
def get_method_for_class(klass)
name = @key_strategy.call klass.model_name
get_method_for_string name
end
def get_method_for_string(str)
names = method_names
names[str] || names.compute_if_absent(-str.to_s) { -"#{prefix}#{str}_#{suffix}" }
end
# Builders are frozen and shared across Ractors (see the make_shareable
# call below), so the per-builder memo lives in Ractor-local storage.
def method_names
ActiveSupport::Ractors.store_if_absent(@method_names_key) { Concurrent::Map.new }
end
[nil, "new", "edit"].each do |action|
CACHE[:url][action] = build action, "url"
CACHE[:path][action] = build action, "path"
end
ActiveSupport::Ractors.make_shareable(CACHE)
end
end
end
end
Defined in actionpack/lib/action_dispatch/routing/polymorphic_routes.rb line 164
· View on GitHub
· Improve this page
· Find usages on GitHub
Defined in ActionDispatch::Routing::PolymorphicRoutes