-
Notifications
You must be signed in to change notification settings - Fork 213
AR dynamic finders fail when using symbols #67
Comments
I understand how you feel, but I think that if it causes people to fix already-questionable code, it's a worthwhile tradeoff. Sorry :( |
Good point :) On Oct 1, 2011, at 9:54 AM, Ernie Miller
|
Rails queries eventually get passed to this method: That method enumerates the legal classes for a query value: Relation, Array, Range, AR::Base…. The big case statement ends with an "else" clause, which explicitly allows any object to be used as a query value. Note that String does not appear in that list; it's handled by the else clause. Values passed through that else clause eventually have their to_s method called in the bowel of Arel. In short, Rails queries are built to allow any value that responds to the to_s method (which include symbols). Call it questionable or not, but squeel is explicitly narrowing the set of valid inputs on existing ActiveRecord methods. That is a Bad Thing™. |
Another good point! |
I think you are misunderstanding the point of that "else". It's to It's also possible to pass in other kinds of ARel nodes directly as a In short, the point of the else in this code is to indicate that other Sent from my iPhone On Oct 3, 2011, at 12:17 AM, pcantrell
|
Wrong. Disagreeing about it.
…which is what you're doing, in effect.
Indeed, the weakness of the specification is the root problem. The docs neither explicitly allow nor explicitly disallow symbols. It seems to me that in the absence of a clear answer, the right behavior is to leave AR alone. Your site: "Squeel enhances the normal ActiveRecord query methods." Not "Squeel changes the ActiveRecord query methods." The word "enhances" suggests that existing behavior is preserved. It suggests that I can safely add Squeel to a project and not have existing AR queries break. That is currently not true. I've made my case that it's not Squeel's job to change behavior it doesn't add. I don't think there's much more I can say. It sounds like you're not open to changing your mind, and our immediate problem is easily fixed. |
On Oct 3, 2011, at 12:15 PM, pcantrell wrote:
I'm not restricting a value, I'm specifying a contextually-relevant behavior where no behavior was previously specified (note that I say "specified" here, not "provided"). I don't think it's a huge stretch to say that the most sensible mapping for a Ruby identifier is a database identifier, at AR's abstraction layer.
I don't really feel that's a fair assertion, in this case. If the behavior you previously observed were actually specified somewhere, that would be one thing. I'd probably still opt to change it, because AR already has a way of saying "string value", and that's "use a String", but I'd at least flag the caveat. I don't think it's reasonable to cry foul when a library breaks undocumented and (I would contend) unintentional use cases. |
I don't follow the argument. What's the new contextually relevant behavior you're adding? I thought you were only breaking behavior. Maybe there's a part of this equation I'm missing.
But Rails isn't really specified, only documented. Most of Ruby itself is not specified. (The JRuby guys, who are friends of mine, run up against this all the time. All they have to go off of when things get really sticky is Matz's C code and a bunch of forum discussions.) Ain't no JCP for Rails, which is not necessarily a bad thing. Our argument, I think, is about whether this use case really is "unintentional." It's a very common pattern in Ruby to not expect any specific arg type, but simply to call to_s or to_a (or now, in 1.9, more properly to_str or to_ary), or whatever the appropriate converter method is, and see if the object responds. That's what AR does in the absence of Squeel. |
Ernie can correct me if I'm wrong, but I think the contextually-relavent behavior to which he's referring is a symbol should indicate a database identifier, not a column value. |
@hoverlover close -- a column name is an identifier. So, for instance, to find all people with the same first and last name: Person.where(:first_name => :last_name).to_sql
# => SELECT "people".* FROM "people" WHERE "people"."first_name" = "people"."last_name" |
@ernie, right. I knew you meant database column. I was just using your words:
|
…and then of course there's no way to distinguish existing AR queries from this newly added behavior, so there's a tradeoff. Your intransigence about this suddenly makes a lot more sense! |
@pcantrell I'm glad! I don't like to argue a point for no reason... well, most of the time. I just don't see a reasonable way to add the enhancement without breaking the undocumented "feature". |
Yeah, I don't see a good way either. Argument from principles rarely works in software without understand what problem the programmer is actually solving! Glad I (eventually) got it. |
@ernie, regarding your example:
It is actually NOT what stock ActiveRecord produces. Which definitely means that Squeel does change the meaning of that. |
@dnagir You're right -- I was acknowledging that fact when I used it as an example, but giving a basis for my reasoning about it. |
Then I get really confused. That was the main argument against symbols. Especially when guys from rails core team said that it will work in the future rails (even though they don't encourage that). |
Gonna make one last attempt to summon @tenderlove and/or @jonleighton to give an idea at to how bad a person I am for the reasoning given in #67 (comment) and #67 (comment) -- looking to release 1.0 in as kosher (per Rails Core team opinion) a condition as possible, but definitely aiming for before Railsconf is over. Based on the reasoning that @jonleighton gave in https://groups.google.com/forum/?fromgroups#!topic/rubyonrails-core/NQJJzZ7R7S0 I'm gonna guess that I'm not too terribly out of line here. Thanks for all the feedback, in either case. |
@ernie I can't see that we're ever going to have |
@jonleighton ❤️ |
I agree with Jon. :-) Aaron Patterson On Apr 22, 2012, at 1:26 PM, Jon Leightonreply@reply.github.com wrote:
|
@tenderlove ❤️ ❤️ (You get two of them because without your tireless efforts on ARel (and willingness to accept way too many of my pull requests!) Squeel wouldn't even be possible. THANK YOU! ❤️ |
Thanks a lot guys. So it's officially settled - symbols should not be used. |
AR finders like
find_by_name :john
fail when the squeel gem is installed, but when removed they work just fine. I'm not sure I agree with using a symbol for the value, but Rails allows it. This can cause confusion if a project already has symbols in it's code, and then introduces squeel, only to start getting errors.I've created a sample project with specs that show the behavior that fails. Let me know if you need anything else.
The text was updated successfully, but these errors were encountered: