Relationship issues....

31 views
Skip to first unread message

pruchai

unread,
Jan 22, 2015, 5:50:43 PM1/22/15
to rubyonra...@googlegroups.com

Rails relationships that is :)

 

I am doing something wrong, and can't figure out what and where.

 

I have 3 models - Command, Contact, and a joined CommandsContact via has_many through relationship, because commands_contacts table holds an extra column - notification_type, which could be either set to host of service. 

 

Models 

 

contact.rb

 

This one is a special case, because it has 2 extra "virtual" relationships :host_notification_commands and :service_notification_commands, which gives me an ability to selectively get either host or service commands for a user (contact) like this:

 

Contact.first.host_notification_commands or 

Contact.find(3).service_notification_commands etc.

class Contact < ActiveRecord::Base

 has_many :commands_contacts, :inverse_of => :contact
 has_many :commands, :through => :commands_contacts

 has_many :host_notification_commands, -> { where commands_contacts: { :notification_type => 'host' } },
          :through => :commands_contacts,
          :class_name => 'Command', 
          :source => :command

 has_many :service_notification_commands, -> { where commands_contacts: { notification_type: 'service' } },
          :through => :commands_contacts,
          :class_name => 'Command', 
          :source => :command

 accepts_nested_attributes_for :host_notification_commands
 accepts_nested_attributes_for :service_notification_commands

end

command.rb

class Command < ActiveRecord::Base

  has_many :commands_contacts, :inverse_of => :command
  has_many :contacts, :through => :commands_contacts

  accepts_nested_attributes_for :commands_contacts

end

commands_contracts.rb

class CommandsContact < ActiveRecord::Base

 belongs_to :command
 belongs_to :contact

 accepts_nested_attributes_for :command
 accepts_nested_attributes_for :contact

end

So far. So good. This works as expected (i think?) as I am able to manually create relationships, as long as i have a contact and a command already. 

contact = Contact.first
command = Command.find(7)
contact.host_notification_commands << command

Aaand after this things start to go down south, because a Controller, strong_parameters and accepts_nested_attributes_for come into play, and this is where I fail. 

 

My assumption is that Rails will be able to handle this for me and establish the relationship, right? 

def create
  contact = Contact.new safe_params
  contact.save
end

Because I use accepts_nested_attributes_for, I have to append _attributes to the names of nested objects, right? So i do a simple re-assignment here and then permit them with strong_parameters.

private
def safe_params

  params[:contact][:host_notification_commands_attributes] = params[:contact][:host_notification_commands]
  params[:contact][:service_notification_commands_attributes] = params[:contact][:service_notification_commands]
  
  params.require(:contact)
      .permit(:contact_name, 
        :host_notification_commands_attributes => [ :id, :command_name, :command_line, :command_description ],
        :service_notification_commands_attributes => [ :id, :command_name, :command_line, :command_description ])

 

 

As far as I understand, this is all that needs to be done and Rails should handle the rest, right? The problem is that it does not even try to to establish a relationship. It does a SELECT and immediately fails.

 

When I try to create a new record, it fails with:

 

ActiveRecord::RecordNotFound (Couldn't find Command with ID=1 for Contact with ID=):


Because it hasn't yet created a user a hasn't established a relationship. 

 

When I try to edit and existing contact and establish a relationship with existing command, it fails with

 
   (0.1ms)  BEGIN
  Command Load (0.2ms)  SELECT `commands`.* FROM `commands` INNER JOIN `commands_contacts` ON `commands`.`id` = `commands_contacts`.`command_id` WHERE `commands_contacts`.`contact_id` = 3 AND `commands_contacts`.`notification_type` = 'host' AND `commands`.`id` = 1
   (0.1ms)  ROLLBACK
Completed 404 Not Found in 6ms
 
ActiveRecord::RecordNotFound (Couldn't find Command with ID=1 for Contact with ID=3):
 
Uhm... Of course this relationship record is not found. I am trying to create it! Why does it run SELECT instead of UPDATE / INSERT ?
 
 
So, something tells me I have this relationship defined incorrectly somewhere in my models.... but where? How do i troubleshoot this? 

pruchai

unread,
Jan 25, 2015, 2:34:06 PM1/25/15
to rubyonra...@googlegroups.com
I got a suggestion that format of the data i'm POSTing may be  incorrect, so I made a simple Rake task to remove external factors from the equation, but getting the same result as before, which leads me to believe the problem is somewhere in my models. But where? 

Reply all
Reply to author
Forward
0 new messages