5

configs/routes.rb Shutters and Paints are subresources of Jobs.

resources :jobs do
    resources :shutters
    resources :paints
end

app/models/job.rb A Job contains many Shutters and many Paints.

class Job < ActiveRecord::Base
    has_many :shutters, dependent: :delete_all
    has_many :paints, dependent: :delete_all

    accepts_nested_attributes_for :shutters, allow_destroy: true, :reject_if => lambda { |a| a[:no].blank? }
    accepts_nested_attributes_for :paints, allow_destroy: true, :reject_if => lambda { |a| a[:name].blank? }`

app/models/shutter.rb A Shutter contains belongs to one Job and one Paint.

class Shutter < ActiveRecord::Base
    belongs_to :job
    belongs_to :paint

app/models/paint.rb A Paint belongs to one Job but can be referenced by many Shutters in that job.

class Paint < ActiveRecord::Base
    belongs_to :job
    has_many :shutters

Both Jobs#show and Jobs#edit work fine with the code <%= debug @job.paints %> if there are no Paints already in the database. But the moment a paint is added, a RuntimeError is raised, "Circular dependency detected while autoloading constant PAINT".

What's the best way to fix this error?

Edit: Controller info

app/controllers/jobs_controller.rb

class JobsController < ApplicationController
    before_action :set_job, only: [:show, :edit, :update, :destroy]

    ...

    # GET /jobs/1
    # GET /jobs/1.json
    def show
    end

    # GET /jobs/new
    def new
        @job = Job.new
        @job.shutters.build
        @job.paints.build
    end

    # GET /jobs/1/edit
    def edit
        @job.shutters.build
        @job.paints.build
    end

app/controllers/shutters_controller.rb

class ShuttersController < ApplicationController
    def new
        @shutter = Shutter.new
    end

    def destroy
        @shutter = Shutter.find(params[:id])
        @job = Job.find(@shutter[:job_id])
        @shutter.destroy
        respond_to do |format|
            format.html {redirect_to @job, notice: 'Shutter was succesfully deleted.' }
        end
    end
end

app/controllers/paints_controller.rb

class PaintsController < ApplicationController
    def new
        @paint = Paint.new
    end

    def destroy
        @paint = Paint.find(params[:id])
        @job = Job.find(@paint[:job_id])
        @paint.destroy
        respond_to do |format|
            format.html {redirect_to @job, notice: 'Paint was succesfully deleted.' }
        end
    end
end
dpyro
  • 1,559
  • 2
  • 13
  • 19
  • What does your controller code look like for adding 'paints' – Eyeslandic May 21 '14 at 18:16
  • @Iceman added controller code to my post. – dpyro May 21 '14 at 18:25
  • @Iceman None is needed as far as I know. They key thing is that the `Shutter` model works perfectly fine with the same code. I just copy-pasted for the `Paint` controller. The actual creation logic is in the `JobsController` for both models. – dpyro May 21 '14 at 19:53

1 Answers1

15

The problem was none of these. It was actually that my Paint model contained a field named :type, which is a reserved keyword for meta-classing or something as such. Was thankfully helped by the kind folks at #RubyOnRails, else a newbie like me would have tried to start from scratch, run into the same problem, and would have never have figured this out. Hopefully this helps some future Googler. Pay it forward!

dpyro
  • 1,559
  • 2
  • 13
  • 19
  • 1
    Thanks; I ran into the exact same issue. It's always great when new reserved keywords are added... – bigtunacan Jun 23 '14 at 14:41
  • @bigtunacan It was always my dream to help the poor Googling soul stumped by some seemingly impossible error. I'm glad I was able to provide back to the community! – dpyro Sep 03 '14 at 16:11
  • 6
    Does anyone of you know a resource with a complete list of reserved keywords? We also get this error randomly when running our specs. But as I can see, we do not use reserved keywords in any of our models... – mfittko Oct 31 '14 at 13:21
  • @mfittko - This might be useful: http://bparanj.blogspot.in/2011/07/reserved-words-in-rails.html – Radhika Jul 01 '15 at 09:30
  • As clarification, the `type` field in Rails is used for "single table inheritance". Basically it allows you to subclass your models, and have all of the subclasses stored in a single database table. `type` would differentiate your `Dog` subclass from your `Animal` class while storing them in the same database table – Peter Klipfel Mar 17 '17 at 15:43