Update_attributes fails: ReadOnlyRecord


#1

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


#2

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


#3

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 S. 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