1

invitation.rb is as:

class Invitation < ApplicationRecord . 
  belongs_to :sender, class_name: 'User'
  belongs_to :subscription
end  

subscription.rb is as:

    class Subscription < ApplicationRecord
      has_many :payments, dependent: :destroy
      has_one :invitation, 
      belongs_to :plan
      belongs_to :user  
    end  

and the migration file for adding column subscription_id in invitations is as:

    class AddSubscriptionIdToInvitations < ActiveRecord::Migration[5.1]
      def change
        add_reference :invitations, :subscription, foreign_key: true
      end
    end

Although I haven't specified validation rule in Invitation model for subscription_id presence. But I get error 'Subscription not present', when I do below code:

    @invitation = Invitation.create_with(
          message: invitation_params.delete(:message),
          first_name: invitation_params.delete(:first_name),
          last_name: invitation_params.delete(:last_name),
        ).find_or_create_by(
          receiver: receiver,
          sender: current_user
        )  

Rails version = 5.1.4 and ruby version = 2.4.3. Thank you.

codemilan
  • 1,072
  • 3
  • 12
  • 32

2 Answers2

2

It is because of the foreign_key: true. You are getting an error in the database level and not in the application (models).

As it is explained in the Foreign Keys and Active Record and Referential Integrity sections of the Active Record Migrations Rails guide, you can add foreign key constraints to guarantee referential integrity. The Active Record way (validations) claims that intelligence belongs in your models, not in the database. Like anything which operates at the application level, these cannot guarantee referential integrity and and that's why you might want to use foreign key constraints in the database (if you want the relation to always exist).

So if you remove the foreign key, you won't get the error anymore. You can do this with remove_foreign_key.

  • Yes you are wright somehow, but this is not the actual answer. Thank you @Ana María Martínez Gómez. – codemilan Jun 26 '18 at 05:55
  • 1
    Why is this not the actual answer? :| – Ana María Martínez Gómez Jun 28 '18 at 07:51
  • The answer is not perfect because: i) Mentioned error comes from ActiveRecord not from the db adapter(db adapter raises exceptions, doesn't build errors). ii) We can disable presence_validation even by keeping foreign_key: true constraint. Hoping the point makes sense. – codemilan Jun 28 '18 at 15:10
0

Starting from rails 5, belongs_to has option 'optional' which is false in default, thats why belongs_to relation has presence validation in default. To remove the validation we need to do as below:-

class Invitation < ApplicationRecord . 
  belongs_to :sender, class_name: 'User'
  belongs_to :subscription, optional: true
end  
codemilan
  • 1,072
  • 3
  • 12
  • 32