Validation in a 3-level association

I have 3 models, say A, B and C, and they are set up like this:

A:   has_many :Bs   has_many :Cs, through: B

B:   belongs_to A:   has_many :Cs

C:   belongs_to B:

In my model for C, I want to declare, that a column ccol within C must be unique, but only within the scope of a certain A.

If the constraint would require uniqueness within a certain B, I could write

  validates :ccol, uniqueness: { scope: :B_id }

But since C doesn't contain an A_id as foreign key, I can not express it in this way.

Is there a possibility to achieve this?

Ronald

With a custom validation, you can theoretically do anything :slight_smile:

That said: consider that your expressed goal is a Law of Demeter violation, and might be reason to rethink your models?

Hard to say more without understanding the actual domain...

FWIW,

I think that the relationships in my model are OK so far. In my concrete case, an instance of A would be a so-called (domain-specific) user dictionaries. An instance of B would be a dictionary entry (each dictionary has many entries). A C would be a so called idiom description, i.e. explaining the associated B object in different ways. Hence, each entry would contain several idioms.

The idiom description has among their columns are two fields which are called "representation" and "kind". In theory, the catenated key of "representation" and "kind" must be unique within a dictionary (different dictionaries may have the same [representation,kind] pair though). For the discussion of this posting, I didn't mention the presence of the "kind" column, since it just complicates the fact, and is not really important here for various reasons.

I could add to C a foreign key to A, and then express my validation with the help of this key, but it seems to me pointless to introduce a new column only for this purpose.

I am aware that I could do a custom validation, but I thought that the case my case is commonplace, that Rails maybe has some built-in feature for this which I just am not aware of.

Ronald