Forum: Ruby on Rails update_attributes fails: ReadOnlyRecord

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
6e7ddb6784d284c385f3f0f307ebf90d?d=identicon&s=25 Christian Johansen (chrisjo)
on 2006-12-29 16:55
I'm trying to update a record, but it just stops with
"ActiveRecord::ReadOnlyRecord". I don't understand why, because I never
wanted my model to be read only. Relevant code:

Controller:
  def edit
    @project = find_project

    if request.post?
      @project.update_attributes(params[:project])

      if @project.save
        flash[:message] = _('Project was updated')
        redirect_to :action => 'index'
        return
      else
        flash[:warning] = _('Could not update project')
      end
    end
  end

Model:
class Project < ActiveRecord::Base
  belongs_to :client
  has_many :tasks

  validates_length_of :name, :within => 2..100
  validates_length_of :url, :within => 2..100
  validates_uniqueness_of :url, :scope => :client_id
27c170f482104299af279902be0a9c26?d=identicon&s=25 Trevor Squires (Guest)
on 2006-12-29 17:36
(Received via mailing list)
Hey,

you don't show what find_project() does but I'll guess that you've
got a :joins option in your call to find(), in which case AR will
set :readonly to true on your returned objects because they will have
additional attributes that don't map to columns in your @project
object's table.

Check the ActiveRecord::Base#find documentation for more information
(and how you can pass :readonly => false to override).

Next, you are doing @project.update_attributes() on one line and then
immediately below you are doing @project.save() - you do realize that
update_attributes() writes to the database right?  So you're saving
to the database twice there.

Regards,
Trevor
6e7ddb6784d284c385f3f0f307ebf90d?d=identicon&s=25 Christian Johansen (chrisjo)
on 2006-12-29 17:48
Thanks alot! I did not know that update_attributes did the saving as
well, shame on me. The find_project method simply finds a project based
on client and projects urls, and I don't see why the project is returned
readonly. However, passing readonly = false fixed the problem.

  private
    # Finds a project based on the available request parameters
    # Allows for urls like /cilents/:client_url/projects/:project_url
    def find_project(readonly = true)
      @current_user.projects.find_by_url(
          params[:project_url],
          :readonly => readonly,
          :conditions =>
               ["client_id = (select id from clients where url = ?)",
params[:client_url]])
    end

Trevor Squires wrote:
> Hey,
>
> you don't show what find_project() does but I'll guess that you've
> got a :joins option in your call to find(), in which case AR will
> set :readonly to true on your returned objects because they will have
> additional attributes that don't map to columns in your @project
> object's table.
>
> Check the ActiveRecord::Base#find documentation for more information
> (and how you can pass :readonly => false to override).
>
> Next, you are doing @project.update_attributes() on one line and then
> immediately below you are doing @project.save() - you do realize that
> update_attributes() writes to the database right?  So you're saving
> to the database twice there.
>
> Regards,
> Trevor
This topic is locked and can not be replied to.