doug316
2011-Nov-02 07:13 UTC
Specify and validate requirements on an ActiveRecord association
Looking for some guidance/support on what feels like might not be an uncommon use-case. `User.has_many accounts` `User.has_many payment_methods` `Account.belongs_to :user` `Account.belongs_to :payment_method` `PaymentMethod.has_many :accounts` There are lots of `Accounts`. When I (a `User`) want to assign accounts to a `PaymentMethod`, I really don''t want to scope against all of them, but rather only those that I own. While this can be done at the controller level, it feels like a data-level constraint. I will want a validation, to ensure I do not map `PaymentMethods` to `Accounts` with different `Users`. But I will also want a way to specify the scope of possible associations, effectively using the same logic as the validation. Placing conditions on the association doesn''t restrict invalid associations, nor does it imply that. A useful syntax might be: `PaymentMethod.has_many :accounts, requirement: proc {self.user =target.user}, scope: true, validate: true` Expressing `my_payment_method.accounts` would use `requirement` as a condition. A reflection on the association (`PaymentMethod.possible_accounts`) could return a relation that could be used to scope out the possible valid associations from the target (`Accounts`). The validate flag could generate a matching DRY validation that ensures the same condition at the instance level. Realizing that crossing realms of associations and validations might not be the most desirable, but seem inherently required in order to avoid repetition. Does anyone have any insight on this? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2011-Nov-02 08:34 UTC
Re: Specify and validate requirements on an ActiveRecord association
On 2 Nov 2011, at 07:13, doug316 <doug316-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Looking for some guidance/support on what feels like might not be an > uncommon use-case. > > `User.has_many accounts` > `User.has_many payment_methods` > `Account.belongs_to :user` > `Account.belongs_to :payment_method` > `PaymentMethod.has_many :accounts` > > There are lots of `Accounts`. When I (a `User`) want to assign > accounts to a `PaymentMethod`, I really don''t want to scope against > all of them, but rather only those that I own. While this can be done > at the controller level, it feels like a data-level constraint. > > I will want a validation, to ensure I do not map `PaymentMethods` to > `Accounts` with different `Users`. But I will also want a way to > specify the scope of possible associations, effectively using the same > logic as the validation. Placing conditions on the association doesn''t > restrict invalid associations, nor does it imply that. > > A useful syntax might be: > > `PaymentMethod.has_many :accounts, requirement: proc {self.user => target.user}, scope: true, validate: true` > > Expressing `my_payment_method.accounts` would use `requirement` as a > condition. A reflection on the association > (`PaymentMethod.possible_accounts`) could return a relation that could > be used to scope out the possible valid associations from the target > (`Accounts`). The validate flag could generate a matching DRY > validation that ensures the same condition at the instance level. > > Realizing that crossing realms of associations and validations might > not be the most desirable, but seem inherently required in order to > avoid repetition. > > Does anyone have any insight on this?You could add a validation to account that checks that payment_method.user_id is the same as user_id. Another approach would be to change your schema. Would this work? user has_many payment_methods user has_many accounts, :through => :payment_methods Payment method is unchanged and for account you''d probably need has_one :through to get at the user To me, the advantage of this method is that the case of an account having a payment_method from the wrong account becomes simply impossible to express. Fred.> > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
fullware
2011-Nov-03 15:38 UTC
Re: Specify and validate requirements on an ActiveRecord association
Thanks for replying. This is solvable with a combination of validations and controller logic, but I''m considering a syntax that would capture the constraint on the association that I''m thinking might not be so uncommon. Maybe extending ActiveRecord. A change of schema would depart from the business need of he data architecture. On Nov 2, 1:34 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 2 Nov 2011, at 07:13, doug316 <doug...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > > > > > Looking for some guidance/support on what feels like might not be an > > uncommon use-case. > > > `User.has_many accounts` > > `User.has_many payment_methods` > > `Account.belongs_to :user` > > `Account.belongs_to :payment_method` > > `PaymentMethod.has_many :accounts` > > > There are lots of `Accounts`. When I (a `User`) want to assign > > accounts to a `PaymentMethod`, I really don''t want to scope against > > all of them, but rather only those that I own. While this can be done > > at the controller level, it feels like a data-level constraint. > > > I will want a validation, to ensure I do not map `PaymentMethods` to > > `Accounts` with different `Users`. But I will also want a way to > > specify the scope of possible associations, effectively using the same > > logic as the validation. Placing conditions on the association doesn''t > > restrict invalid associations, nor does it imply that. > > > A useful syntax might be: > > > `PaymentMethod.has_many :accounts, requirement: proc {self.user => > target.user}, scope: true, validate: true` > > > Expressing `my_payment_method.accounts` would use `requirement` as a > > condition. A reflection on the association > > (`PaymentMethod.possible_accounts`) could return a relation that could > > be used to scope out the possible valid associations from the target > > (`Accounts`). The validate flag could generate a matching DRY > > validation that ensures the same condition at the instance level. > > > Realizing that crossing realms of associations and validations might > > not be the most desirable, but seem inherently required in order to > > avoid repetition. > > > Does anyone have any insight on this? > > You could add a validation to account that checks that payment_method.user_id is the same as user_id. > > Another approach would be to change your schema. Would this work? > > user has_many payment_methods > user has_many accounts, :through => :payment_methods > > Payment method is unchanged and for account you''d probably need has_one :through to get at the user > > To me, the advantage of this method is that the case of an account having a payment_method from the wrong account becomes simply impossible to express. > > Fred. > > > > > > > > > > > -- > > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > > For more options, visit this group athttp://groups.google.com/group/rubyonrails-talk?hl=en.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Reasonably Related Threads
- belongs_to causing endless loop on first call to save!
- Problem w/ActionWebService and Inheritance in Service Params
- Association extension method
- Using Reflections to find out ActiveRecord class association
- More than one has_many :through association between the same 2 models