I'm happy to provide some real code from our app if that helps? What I don't understand is why there needs to be a way to reload has_many but not a way to reload has_one.
In our apps most has_ones are related to a has_many, for example picking the "active" one. We need to reload the has_many when something may have changed the list. We need to find the new "active" one in the same situation. Totally fine with any API but to argue that has_many has needs that has_one does not share seems very strange. Do you see where I'm coming from? > On 17/07/2015, at 01:59, DHH <[email protected]> wrote: > > I'm comfortable with those trade-offs. Barring any compelling real world code > shining a different light on the discussion than what we've covered so far, I > don't think we're going to make any additional progress discussing it. > >> On Thursday, July 16, 2015 at 3:12:56 PM UTC+2, will.bryant wrote: >> Oh, sorry, I explained that badly. >> >> I’m not saying it’s a performance problem doing two queries. I’m saying >> it’s causing unintended side-effects, because when you do the query on the >> parent it resets the attributes, including blowing away unsaved changes. >> This is absolutely undesirable if you just want to make sure you have the >> current child. >> >> How is it trivial to implement reload_manager on its own, BTW? You would >> have to write out the foreign key SQL, do the query, and then assign back to >> the association? >> >> >>> On 17/07/2015, at 01:07 , DHH <[email protected]> wrote: >>> >>> I'd be happy to consider some real code from a real project that shows the >>> use of reloading a single has_one association in a performance hotspot >>> where two ID lookups are proving to be a problem. But for the time being, >>> I'm content with the trade off that has collection#reload and record#reload >>> as the two only ways to reloading those associations. And if someone needs >>> #reload_manager in their model because they do use that a lot, it's trivial >>> to implement on its own. >>> >>> Do appreciate the debate over this, though! Good to go through the >>> reasoning of why we do and make certain changes. >>> >>>> On Thursday, July 16, 2015 at 2:28:14 PM UTC+2, will.bryant wrote: >>>> I think you’re right that we can’t have complete parity, but then as you >>>> said, it would be good to have a single API. >>>> >>>> It does works well right now having the same API to always get the fresh >>>> association loaded, and it is useful to be able to definitely get the >>>> current record, even if you don’t personally use it that often :). >>>> >>>> There is a practical difference between the current project.manager(true) >>>> which always does exactly one query, whether or not manager is already >>>> loaded, and project.reload.manager, which always does two queries and also >>>> changes other stuff on the project instance. >>>> >>>> Surely it is not necessary to take away the ability to do exactly one >>>> association reload? >>>> >>>> Otherwise you could just as equally argue that there is no use for reload >>>> on a has_many. Personally I think I reload has_ones as often as I reload >>>> has_manys, and for the same reasons - I need to be sure I am dealing with >>>> the current child/children of an object I am halfway through doing stuff >>>> to (which is why I don’t want to reload the parent). >>>> >>>> >>>>> On 17/07/2015, at 00:17 , DHH <[email protected]> wrote: >>>>> >>>>> I think the first assumption to challenge is that we can have parity >>>>> between a collection and a single object. I don't think we can or should. >>>>> An array of strings does not have parity with a single string. >>>>> >>>>> So project.manager.reload will call ActiveRecord::Base#reload, so that's >>>>> a Manager.find(id) call, not a Manager.find_by(project: x) call. If you >>>>> absolutely need the latter, you can do project.reload.manager. I've found >>>>> this to be an exceedingly rare case, though. So I'm find have it be a >>>>> round-about to get there, and I'm fine not having parity between >>>>> collection and record. >>>>> >>>>>> On Thursday, July 16, 2015 at 2:09:22 PM UTC+2, will.bryant wrote: >>>>>> OK, so what about the has_one case? >>>>>> >>>>>> Say Project has_one :manager, and project.manager is already loaded >>>>>> (which did a "SELECT * FROM managers WHERE project_id = ?"), will >>>>>> project.manager.reload do another "SELECT * FROM managers WHERE >>>>>> project_id = ?", or will it do a "SELECT * FROM managers WHERE id = ?”. >>>>>> >>>>>> To match the has_many I would expect the former, and sometimes we need >>>>>> this behavior if this is the only way to force the association to be >>>>>> looked up again (whereas currently we can do project.manager(true)). >>>>>> >>>>>> But because the object returned by project.manager looks like it is just >>>>>> a plain record instance, I’d expect #reload to behave like the query, a >>>>>> regular find(id). Especially if I call reload(:lock => true). >>>>>> >>>>>> It seems a big ambiguous what the behavior would be for has_one, which >>>>>> makes me think the original project.manager(:reload => true) is clearer >>>>>> - and then reload on the target of a belongs_to or has_one should always >>>>>> just reload that instance, not load a potentially different record. >>>>>> >>>>>> Do you agree? >>>>>> >>>>>> >>>>>>> On 16/07/2015, at 23:59 , DHH <[email protected]> wrote: >>>>>>> >>>>>>> project.documents.reload.first would reload the documents association, >>>>>>> then grab the first entry in that array – not trigger another find(id). >>>>>>> Like calling #load, but ignoring whether it had already been loaded. >>>>>>> >>>>>>>> On Thursday, July 16, 2015 at 12:53:31 AM UTC+2, will.bryant wrote: >>>>>>>> So are you saying project.documents.reload.first would redo the query >>>>>>>> to find the associated record, or would do a find(id) to reload the >>>>>>>> current instance? >>>>>>>> >>>>>>>> >>>>>>>>> On 16/07/2015, at 01:08 , DHH <[email protected]> wrote: >>>>>>>>> >>>>>>>>> I'd prefer to see us move to a single API, and IMO the trade-offs for >>>>>>>>> #reload alone fits the bill. There's no contract saying that a >>>>>>>>> singular object from has_one/belongs_to and a collection like >>>>>>>>> has_many has to behave the same. In fact, I think it'd be strange to >>>>>>>>> think that it should. A single string and an array of strings do not >>>>>>>>> behave the same. >>>>>>>>> >>>>>>>>> So project.documents.reload.first makes perfect sense to me as >>>>>>>>> reloading the documents collection, then grabbing the first one. >>>>>>>>> projects.owner.reload.name makes sense to me as reloading the owner >>>>>>>>> record itself, then fetching the name (if we don't already return >>>>>>>>> self from Record#reload, we should). >>>>>>>>> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "Ruby on Rails: Core" group. >>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>> send an email to [email protected]. >>>>>>>>> To post to this group, send email to [email protected]. >>>>>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core. >>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "Ruby on Rails: Core" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>>>> an email to [email protected]. >>>>>>> To post to this group, send email to [email protected]. >>>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core. >>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google Groups >>>>> "Ruby on Rails: Core" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send an >>>>> email to [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> Visit this group at http://groups.google.com/group/rubyonrails-core. >>>>> For more options, visit https://groups.google.com/d/optout. >>> >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Ruby on Rails: Core" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/rubyonrails-core. >>> For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/rubyonrails-core. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.
