ruby-on-rails – Ruby on Rails scoped association

Question:

I have a Ruby on Rails application in which I have licenses, items that can be licensed and a table that lists the two (which items in what quantity are present in the license?). Analogous to items in a shopping cart.

Some of the items will no longer be sold, but I intend to keep them in the database. So I created a soft-delete and used a default scope for the model and for the relationships. But when I try to change existing records using the related model, I get an exception: ActiveRecord::ReadOnlyRecord

My models look like this:

class Item < ActiveRecord::Base
  default_scope { where(deleted:false) }
end

class LicenseItem < ActiveRecord::Base
  belongs_to :license, touch: true
  belongs_to :item
end

class License < ActiveRecord::Base
  has_many :license_items,  
          -> { joins(:item).where(items: {deleted: false} ) }, 
          dependent: :destroy
end

In this way:

pry(main)> License.find(0).license_items[0].readonly?
=> true

Is there any way to make this relationship not read-only?

I've tried to add readonly(false) to the end of the has_many scope in License no avail.

Answer:

According to this discussion on GitHub , this is a Rails 4.0 bug, which was fixed in version 4.0.1. By updating your Rails, you can include readonly(false) in your scope and it will work:

class License < ActiveRecord::Base
    has_many :license_items,  
          -> { joins(:item).where(items: {deleted: false}).readonly(false) }, 
          dependent: :destroy
end

To update your Rails version, edit your Gemfile and then run bundle update .

As a last resort, if you are unable to update your Rails version, you can pass the readonly: false option to the find method (not recommended):

License.find(1).license_items.find(1, readonly: false).update_attributes(amount: 5)
Scroll to Top