Add :touch option to has_many associations

Hi,

it would be nice to have the touch option in has_many associations also.

I have a scenario like this:

An user has some credit (money) and some advertises. Each advertise can be enabled or disabled depending on some rules. One of the rules is that the user should have money. Each time the money of the user change, the advertises are touched, enabled/disabled and then cached, as they are much more requested that updated.

I have created a ticket with a patch attached:

https://rails.lighthouseapp.com/projects/8994/tickets/4392-add-touch-option-to-has_many-associations

cheers

"Diego Carrion" <dc.rec1@gmail.com> wrote in message news:m2pc455cfa11004151155x9d1affb0r1bfcbb4de166b240@mail.gmail.com... Hi,

it would be nice to have the touch option in has_many associations also.

It exists in belongs_to already, right?

Does it also already exist in has_one? If not it would be odd to have it in has_many but not in has_one.

If has_many has :touch, then has_and_belongs_to_many should also get :touch too, no? There it is thankfully equivlent if you thing of this thouch as belonging to either the has_ or belongs_ side of said relationship.

Yes, it exists in belongs_to already.

It doesn’t exists in has_one.

I added the option to has_many because I really needed it, I prefer to add functionalities on demand.

If you think it will be useful to implement the option in has_one and has_and_belongs_to_many associations, I can do it without problems :slight_smile:

"Diego Carrion" <dc.rec1@gmail.com> wrote in message news:p2pc455cfa11004171655l1300ccaehd146e09577f6b6f6@mail.gmail.com...

Yes, it exists in belongs_to already.

It doesn't exists in has_one.

I added the option to has_many because I really needed it, I prefer to add >functionalities on demand.

Adding functionality on demand is a great way to write applications. It is the basis of TDD and BDD. But it does not work quite as well for frameworks in my opinion.

For a framework to work well it should be consistant. I should be able to guess functionaility based on what I already know, rather than having to look it up. Rails generally does quite well with that.

If you think it will be useful to implement the option in has_one and >has_and_belongs_to_many associations, I can do it without problems :slight_smile:

I would like it, but I am a nobody, just a regular rails user, so don't assume my stances are shared by the core team.

My thoughts are that here it would be inconsistant to not implement it on all 3 has_* associations. My gut tells me that there is nothing special about the has_many case that would justify only it having this feature.

Agree with that. If has_many has :touch option, it would be great to all of has_* to have that functionality too.

Diego, could you submit a patch for this? :slight_smile:

- Prem S.

Thans for the feedback, I added the touch support to has_one associations also.

I'm a little concerned that adding :touch to has_many and friends is encouraging bad practice (and terrible performance) when there's almost certainly a more performant solution available. It seems risky to me to allow a single option on association to cause every instance to be instantiated, changed, and written back to the database.

In your particular case couldn't your cache keys include the updated_at value from a user? Alternatively you can get the behaviour you want with a 1 line after_save function without too much hassle?

Is there a use-case I'm missing here?

Hi Michael,

in my case, an user gets only updated when he puts more money in his account or when some of his money is taken because one of his advertises was clicked. In this moment, all his advertises must be reevaluated to determine if they’re enabled or not.

I agree with you I can add the behavior with one line but it’s less elegant. I thinks this is the reason the belongs_to associations gained the touch option.

I also agree with you this can lead to a bad performance in the application but a lot of things in the Rails framework can lead to a bad performance, too. If a developer is coherent it will use the Rails api with responsibility. If a developer isn’t coherent, I think he will have a bad performance anyway, using Rails api or not.

Beside of that, I think we should worry with performance in the right time. With a clean design, it will be easier to fix the problems when they appear.

cheers

Agree with what Koz said. This isn't needed very frequently and it's easier to just use a before/after save callback if/when it's needed.

Ditto. Using touch actually obscures the intent of your code.

Touch means set updated_at timestamp, that's all. Not "re-evaluate all children."

-1

jeremy

Ok, what about the has_one association?

cheers

the has_one case makes sense, sure.

Hi Michael,

I’ll send the patch with this modification only, thanks.

cheers

Hello guys,

Sorry for revamping this, but I’m having exactly the same use case as described.

The main point for not having this implemented seems to be performance problems of instantiating every model and updating its updated_at field. Should it be doable via a batch update without instantiating any models at all?

quinta-feira, 15 de Abril de 2010 às 19:55:50 UTC+1, Diego Carrion escreveu: