Jeremy Jeremy - 4 months ago 23
MySQL Question

has_many through invisible validations? (rails 5)

I have a setup where I want to be able to build a role record to point to a users skills, venues, productions, groups and so on.

I set it up as a has many through relationship with everything going though roles and roles belonging to everything as so:

class Role < ApplicationRecord
belongs_to :user
belongs_to :skill
belongs_to :production
belongs_to :venue
belongs_to :project
belongs_to :group
end


and set the individual role categories as so:

class Group < ApplicationRecord
has_many :users, through: :roles
end


All are the same, except for users, which of course has lots of detail to the model.

Every table has a name field, and an id field, and the standard timestamp fields.

I set it up to index on the names for each table.

When I try to build a role as record with just a role_id, user_id, and skill_id I get back errors in the console saying I need values for everything.

Does this mean I have to build a has_many through relationship for each type of role with it's own "through"? Or can one has_many through table work in the fashion I envision? And why is it trying to validate the presence of data for each field? Would it be due to indexing?

If i wanted to turn that validation off I'm not even sure where to put the code, as I'm not sure where the validation comes from.

Answer

The default behaviour of Rails 5 belongs_to is that the parent association must be present, so yes, you would need all the fields in order to save a role.

However, to turn off this behaviour, change to:

# config/initializers/new_framework_defaults.rb
Rails.application.config.active_record.belongs_to_required_by_default = false
# this would disable this configuration for the entire application

UPDATE

Another approach would be to figure out the most important associations and ensure those are available and the set an optional tag on the optional associations, like so:

class Role < ApplicationRecord
  belongs_to :user
  belongs_to :skill, optional: true # assume skill & production are optional
  belongs_to :production, optional: true
  belongs_to :venue
  belongs_to :project
  belongs_to :group
end