Rails 3, ActiveRecord, Detecting changes in has_many association - ruby-on-rails

I have the following associations
class User < ActiveRecord::base
has_many :memberships
end
What I would like to do is to detect in the users_controller update action that some memberships have been added or removed from the user.memberships.
Any idea or suggestion on how to implement this?
Thanks for any help.
EDIT: My apologies if the question was not clear.
Users are linked together by a parent-child relationship. This relationship is implemented through memberships to a Family circle.
What I want is that when a child user joins a Classroom circle automagically the parent of the child also joins the same Classroom circle. In other words adding/removing memberships to a child user needs to be propagated to his parents users.

My apologies if the context was not very clear.
So first some context clarification:
Users are linked together by a parent-child relationship. This relationship is implemented through memberships to a Family circle.
What I want is that when a child user joins a Classroom circle automagically the parent of the child also joins the same Classroom circle. In other words adding/removing memberships to a child user needs to be propagated to his parents users.
Now the solution:
The way I have solved this is by adding the after_save and before_destroy methods to the Membership model to check is the user is a child and in that case to create/destroy membership for the parents. There are several tricky edge-cases I had to solve but the code seems to be working fine.
A final note: my first idea was to somehow detect in the user controller that memberships have been added or removed and then check if the user was a child user....

I know I'm late to the party here, but for future travelers ActiveRecord exposes before_add, after_add, before_remove, and after_remove hooks for exactly these scenarios.

Added how? Since the last visit?
If so, then make a "read" boolean column that updates when you visit.
Otherwise, elaborate. :)

Related

Can I make a modification to a child force a validation on a parent when using Active Record Autosave Association?

I am looking for how to trigger a validation on a parent when a child is modified or
deleted.
Some background in case I am asking the wrong question:
I am trying to implement some basic double entry accounting in a Rails app. I have found a couple accounting Gems but they seem poorly maintained and overly complex. I also want to have complete control so I am building it myself.
My abstraction currently is a parent class, Txn (avoiding Transaction becuase although it is not a reserved word, it doesn't play well with Active Record). Txn has meta data about the transaction, as well as many LineItems.
LineItems are pretty simple; they have a debit_amount, credit_amount, account_id, and txn_id. I am trying to enforce a constraint on all LineItems belonging to a single Txn such that the sum of debits == the sum of credits. Autosave Association gets me most of the way there, allowing me to put a validator in Txn, but I want to ensure, at the ORM level, that if a LineItem is updated or deleted, that the parent Txn will re-validate and only allow the LineItem to be updated or deleted if all remaining LineItems balance.
I am hesistant to start messing with callbacks on the
LineItem triggering a change to the Txn for fear of creating cirular logic resulting in a race
condition.
I welcome any suggestions or resources as well as specific steps and or callbacks I should use.
class Txn
has_many :lineItems, autosave: true
end
class LineItem
belongs_to :txn
end

nested resources rails has and belongs to many

Sorry for the generic title, but I'm not sure how to phrase it better at the moment. I finally had some time to start picking up rails again and came across this issue as I was building my models:
Essentially I have a parent resource that has two nested resources. The parent can have many of each child resource and each child resource can have one parent. This part is working fine. The difficulty comes when I want to have a has_and_belongs_to_many relationship between the two child resources. I'm not sure how to implement this so that when I create a new Child 1, I can associate it with multiple existing Child 2's.
Imagine this like I have a User, Dog, and Walk models. The User is the parent, but each dog will have gone on many walks and each walk may have many dogs in it.
I've been looking for any tutorials for this part and have not had much luck. Can someone point me in the direction of a potential solution?
dog.rb
has_and_belongs_to_many :walks
walk.rb
has_and_belongs_to_many :dogs
Creation of object:
#walk = Walk.last
#dog = Dog.last
#walk.dogs << #dog
For this association, you will be having a join table as dogs_walks who won't have a model and will have attributes as dog_id, walk_id and it won't have id as primary key

Rails Has_One Association Seems Illogical, Wrong Way Around

Sorry if this is obvious. I've been using Rails for a while now, but the way the has_one association works still messes with my head. It just hasn't clicked yet.
I am creating a specialized table that creates a list of companies that meet certain criteria necessary for an email mail-out, and which contains info on whether they have been emailed, and have responded to the email (or not.)
Each entry in the email_responder table links to a single company record. So it seems logical to me to say that each responder record has_one company.
However, if I add the has_one to the responder model and then use responder.company I get an error telling me that I need to have a responder_id field in the company record. Which makes no sense to me, the company knows nothing about responders. I'd expect that since the responder has one company, that there'd be a company_id in the responder record not the other way around. It seems bass ackwards.
So, obviously what I've done isn't Railsy, but other than hacking a company method into the responder model I'm not sure what to do about it. Is there another association type in Rails that I haven't discovered yet?
Each entry in the email_responder table links to a single company
record. So it seems logical to me to say that each responder record
has_one company.
That means one company can have multiple responders.
So you need to add company_id column in the responders table.
And the association is like
class Company < ActiveRecord::Base
has_many :responders
end
class Responder < ActiveRecord::Base
belongs_to :company
end
So each record of responder has one company and one company has multiple responders.
It sounds like you want a belongs_to association.

Inheritance from ActiveRecord Object

Lets say there is a activerecord class called user, which is representative of user table of database.
But I have different type of users which have
special functions
special variables
custom relations (Employer has_many companies, Employee belongs_to company :)
But also these users have a lot of functionality in common. So what I want to do is create classes for each different type of user then inherit them from user class.
User < ActiveRecord::Base
Employer < User
Employee < User
Customer < User
What is the best way of doing something like that?
Thanks
A lot of applications start out with a User model of some sort. Over time, as different kinds of users emerge, it might make sense to make a greater distinction between them. Admin and Guest classes are introduced, as subclasses of User. Now, the shared behavior can reside in User, and subtype behavior can be pushed down to subclasses. However, all user data can still reside in the users table.
All you need to do is add a type column to the users table that will hold the name of the class to be instantiated for a given row. Active Record takes care of instantiating the kind of object when it loads it from the database.
This technique is called Single Table Inheritance or STI (for short).
A very good recent article about STI is here: http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html
Have a look to this thread on models subclassing:
Subclassing models in Rails

Rails Model Association Confusion

Hey guys. I have the following models:
Category
Event
Lock
Item
Site
User
Events are basically a "log item". In other words, they will store what action was done on what Item by what User in what Category. Naturally, when I thought about this, I figured it "has one User", "has one Category", "has one Item", and so on. However, this would mean that there would be a foreign key for the Event in any given User row, but this isn't what I want. I want the foreign key in the Event row, since the Event is just giving information as to what User, what Category, etc.
So my understanding is that I should instead say that an Event "belongs to a user", "belongs to a category", etc. and that they each "have many Events" in return, correct? I'm just making sure, because this doesn't read logically as most other associations. I don't need/want to be able to access an event from the other side (i.e. user.event) because it wouldn't make much sense. So if I do this, would I just add the belongs_to call and not the has_one on the other side?
Perhaps I designed this incorrectly.
I eventually want to be able to render a 'log page' filled with rows, reach row described a little something like:
event.user event.action event.item event.category
I don't need/want to be able to access
an event from the other side (i.e.
user.event) because it wouldn't make
much sense. So if I do this, would I
just add the belongs_to call and not
the has_one on the other side?
Add them both(belongs_to and has_many). Sure, user.event doesn't make sense, but user.events does make sense.
Yes, here you want to use a has_many & belongs_to association. In the context of Activerecord, it is the has_many that defines the need for the belongs_to. "If a model (a) has_many of another model (b) then that associated model (b) belongs_to the first model (a)".
Since a user will have many events associated with it, then an event will belong_to a user.
If on the other hand, a user were to only ever have one event associated with it, then these models would have a "has_one" association.

Resources