Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you reference only the persisted records in an active record association

In the edit method of many controllers you initialize a new object and edit existing objects

class MagazinesController < ApplicationController
   def edit
      @magazine = Magazine.find(params[:magazine_id])
      @page = Page.find(params[:id])
      @new_page = @magazine.pages.new
   end
end

However in a view you will often want to cycle through the persisted objects and treat the new object separately

# magazines#edit
%h4 Existing pages
- @magazine.pages.each do |page|
  %p= link_to page, page.title

The problem

...is that the pages association contains both existing (persisted) pages but also the new page which we made via @new_page = @magazine.pages.new.

It's easy to deal with this however it's ugly

%h4 Existing pages
- @magazine.pages.each do |page|
  - if page.persisted?
    %p= link_to page, page.title

I would like to use some assocition method to select only those pages which are persisted:

%h4 Existing pages
- @magazine.pages.persisted.each do |page|
  %p= link_to page, page.title

Is there any way of doing this?

like image 650
Peter Nixey Avatar asked Nov 07 '13 17:11

Peter Nixey


People also ask

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 an ActiveRecord relation?

An instance of ActiveRecord::Base is an object that represents a specific row of your database (or might be saved into the database). Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet).

What is Active Record's 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 ).

What is ActiveRecord in Ruby on Rails?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


2 Answers

You can create in your Page model a persisted scope: scope :persisted, -> { where "id IS NOT NULL" }, which avoids iterating on each associated page to check whether it's a new record or not.

like image 80
Florent2 Avatar answered Sep 18 '22 04:09

Florent2


Another cleaner syntax, using ActiveRecord where.not and still get back an ActiveRecord collection:

- @magazine.pages.where.not(id: nil).each do |page|
    ...
like image 20
Wafiq Avatar answered Sep 20 '22 04:09

Wafiq