New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define Hash#to_query and set Hash#to_param as alias to it; with test cases #15629
Conversation
@@ -1,5 +1,6 @@ | |||
require 'abstract_unit' | |||
require 'active_support/core_ext/object/to_param' | |||
require 'active_support/core_ext/object/to_query' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need this require here?
@egilburg - Please check the updated code. |
🆗 |
I think if Hash#to_param is dependent on to_query then it should require to_query. Please check my Updated PR. |
|
|
Update: I realized that Hash code in to_param.rb does indeed call |
Yes.. 😄 |
I wonder if better design then would be to move Hash's In to_query.rb: # other classes as before
class Hash
# Returns a string representation of the receiver suitable for use as a URL
# query string:
#
# {name: 'David', nationality: 'Danish'}.to_query
# # => "name=David&nationality=Danish"
#
# An optional namespace can be passed to enclose the key names:
#
# {name: 'David', nationality: 'Danish'}.to_query('user')
# # => "user[name]=David&user[nationality]=Danish"
#
# The string pairs "key=value" that conform the query string
# are sorted lexicographically in ascending order.
#
# This method is also aliased as +to_param+.
def to_query(namespace = nil)
collect do |key, value|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
end
end.compact.sort! * '&'
end
alias_method :to_param, :to_query
end And remove the That way to_param.rb remains independent from to_query.rb and the relationship between the two files is cleaner. |
👍 , I think you are right. But instead of defining the method in |
it wont solve problem of to_param and to_query both depending on code in each other. mutual dependencies are generally not good when they can be avoided |
Hey I think |
cc: @senny, @rafaelfranca. |
If apps load both files, behavior should be as-is ( If app for whatever reason loads only the to_param.rb file (that's not supported by Rails API anyways), than the behavior will differ in sense that I don't think any of the above is an API concern. It's more about cleaner and more maintainable code with no implicit or mutual dependencies. |
Its correct. I think we are now in condition for some suggestions. |
@senny : Could You also take a look at this please? |
Hi any updates? |
@@ -58,3 +58,5 @@ def to_param(namespace = nil) | |||
end.compact.sort! * '&' | |||
end | |||
end | |||
|
|||
require 'active_support/core_ext/object/to_query' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would cause circular dependency. For me this implementation should be moved to to_query
and this one be an alias for it.
I have updated the Code, please check again. |
My problem with this patch is if users only include to_param they will not get I think the implementation before this patch is the only one that satisfy all the requirement. But for understand better, what is the motivation of this change? |
Hash.to_param would still work by virtue of Object.to_param. Yes, it'll produce hash.to_s which will probably be not useful to anyone. The motivation is a hidden dependency where code in to_param requires code in to_query, on top of the explicit dependnecy where code in to_query requires to_param. So there's already an implicit circular dependenency, and I wonder if it can be cleaned up. |
I see. It is trick. I don't think we have a proper way to fix. Right now the situation is worse than before. Using I think is better to accept the hidden dependency. Do you have any more suggestion? |
Not really, without level of abstraction/composition which won't be worth the complexity. Except perhaps explicitly require the other class as well. |
If we stay with previous implementation, then the same question you asked will come i.e. |
I think the best option make both files require the same file and have the implementation in the same place. |
hash = { type: 'human', name: 'Nakshay' } | ||
assert_equal "name=Nakshay&type=human", hash.to_query | ||
end | ||
|
||
private | ||
def assert_query_equal(expected, actual) | ||
assert_equal expected.split('&'), actual.to_query.split('&') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also shouldn't we remove split('&')
from here? I think its not required.
Code updated. Please review. |
Hey its been a month, any progress on this issue? |
Define Hash#to_query and set Hash#to_param as alias to it; with test cases
No description provided.