Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if association changed in ActiveRecord?

ActiveRecord offers change tracking, where calling #name_changed? returns true/false depending on whether the name attribute changed between when the model was loaded and now.

Is there an equivalent for associations? I am specifically looking for has_many associations, but all association types would be useful.

Rails 5.2, Ruby 2.5.1

like image 477
François Beausoleil Avatar asked Apr 02 '18 02:04

François Beausoleil


People also ask

What is polymorphic association in Rails?

Polymorphic relationship in Rails refers to a type of Active Record association. This concept is used to attach a model to another model that can be of a different type by only having to define one association.

What is the difference between Has_one and Belongs_to?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.

What is association in Ruby on Rails?

Association in Rails defines the relationship between models. It is also the connection between two Active Record models. To figure out the relationship between models, we have to determine the types of relationship. Whether it; belongs_to, has_many, has_one, has_one:through, has_and_belongs_to_many.

What is Active Record naming convention?

Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns. Foreign keys - These fields should be named following the pattern singularized_table_name_id (e.g., item_id , order_id ).

How to make efficient use of active record associations in rails?

Here are a few things you should know to make efficient use of Active Record associations in your Rails applications: All of the association methods are built around caching, which keeps the result of the most recent query available for further operations. The cache is even shared across methods. For example:

How do I skip the first 11 Records in an association?

For example, if you set offset (11), it will skip the first 11 records. The order method dictates the order in which associated objects will be received (in the syntax used by an SQL ORDER BY clause). If you use the readonly method, then the associated objects will be read-only when retrieved via the association.

What are transitive many-to-many relationships in ActiveRecord?

Such relationships can be called transitive many-to-many as we rely on the presence of other entities to fully capture the semantics of the relationship. Luckily, ActiveRecord allows us to model such relationships with ease. Let’s start by looking at the simplest ActiveRecord many-to-many associations and work our way up.

How to get the model name from the Association name?

If the name of the other model cannot be derived from the association name, you can use the :class_name option to supply the model name. For example, if a part has many assemblies, but the actual name of the model containing assemblies is Gadget, you'd set things up this way:


Video Answer


1 Answers

Ok, not a answer but this is a workaround I came up with.

In my project I was already using the gem audited to keep track of changes on the model I also want to receive changes on. In my case the model is Location and the model I want to check if the location was changes is Employee

In the after_save I then check if there is made an audit on the location and if it's created within seconds. If so, I'm able to check the changes.

Simplified example:

# app/models/location.rb
class Location < ApplicationRecord
  audited
end

# app/models/employee.rb
class Employee < ApplicationRecord
  after_save :inform_about_changes!
  belongs_to :location

  def inform_about_changes!
    last_location_change = location.audits.last
    if last_location_change.created_at.between?(2.seconds.ago, Time.now)
      if last_location_change.audited_changes.include? 'city'
        city_was = last_location_change.audited_changes[0]
      end
    end
  end
end

Once again, this is not an answer, but it did the job in my case

like image 169
Manuel van Rijn Avatar answered Oct 16 '22 03:10

Manuel van Rijn