Skip to content

Instantly share code, notes, and snippets.

@dklisiaris
Last active February 18, 2022 01:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dklisiaris/5ea680fbef07ae3ab41f to your computer and use it in GitHub Desktop.
Save dklisiaris/5ea680fbef07ae3ab41f to your computer and use it in GitHub Desktop.
How do you reference only the persisted records in an active record association.

Setup

Generate models.

rails g model author name:string
rails g model book title:string author:references
bundle exec rake db:migrate

Add associations:

in author.rb

has_many :books

in book.rb

belongs_to :author

in seeds.rb

author = Author.create(name: 'Some author')
author.books.create(title: 'Some book 1')
author.books.create(title: 'Another Book 1')

Seed database:

bundle exec rake db:seed

The Problem

Fire up console:

rails c

Get all books by first author:

first_author = Author.first
all_books = first_author.books

Add a new book to that author without saving it:

some_new_book = first_author.books.new(title: 'A test book')

Lets see books in all_books collection:

all_books.each do |book|
  puts book.title
end

The unsaved book's title appears also which it shouldn't!

The Fix

add scope in book.rb

scope :persisted, -> { where "id IS NOT NULL" }

Now we can fetch only persisted books:

first_author = Author.first
all_books = first_author.books.persisted

Fix 2

Here we 'll use an active record associations extension to fetch only persisted data.

Create the file lib/extensions/active_record_extensions.rb and add this:

module Extensions::ActiveRecordExtensions
  def persisted
    select(&:persisted?)
  end
end

in author.rb change the has_many :books line to this:

has_many :books, extend: Extensions::ActiveRecordExtensions

Make sure the lib path is auto loaded by adding

config.autoload_paths << Rails.root.join('lib')  

in application.rb

Finally we can fetch only persisted books with the same way:

first_author = Author.first
all_books = first_author.books.persisted
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment