Undefined method `target' in Rails associations (1.2)

I’m having trouble with one of my Rails model associations. They seem
simple enough, I have 99% of them working. But in one of them, when I
try to access a foreign key record, I get:

undefined method `target’ for #Environment:0xb766c70c

vendor/rails/activerecord/lib/active_record/base.rb:1848:in
method_missing' vendor/rails/activerecord/lib/active_record/associations.rb:891:inenvironment’
app/models/revision.rb:154:in start' app/controllers/revisions_controller.rb:9:instart’

Has anyone seen this? My associations are:

class Revision < ActiveRecord::Base
belongs_to :environment
belongs_to :source_revision,
:class_name => ‘Revision’,
:foreign_key => ‘source_revision_id’
end

class Environment < ActiveRecord::Base
belongs_to :layout
belongs_to :life_cycle
has_many :revisions
has_many :titles, :through => :environment_titles
end

I’ve tried many different variations, singular/plural, etc. BTW, the
‘source_revision’ one works fine (I tried specifying everything to the
environment belongs_to but it didn’t matter)

Here’s my tables, any clues? I’m REALLY stuck…

SQL> desc revisions;
Name Null? Type



ID NOT NULL NUMBER(38)
REVISION NOT NULL NUMBER(38)
ENVIRONMENT_ID NOT NULL NUMBER(38)
REVISION_TYPE_ID NUMBER(38)
EVENT_ID NUMBER(38)
IS_DEPLOYABLE NOT NULL NUMBER(38)
IS_PROMOTABLE NOT NULL NUMBER(38)
SOURCE_REVISION_ID NUMBER(38)
UPDATED_BY VARCHAR2(64)
UPDATED_AT DATE
CREATED_BY VARCHAR2(64)
CREATED_AT DATE

SQL> desc environments;
Name Null? Type



ID NOT NULL NUMBER(38)
ENVIRONMENT NOT NULL VARCHAR2(64)
ENVIRONMENT_DESC VARCHAR2(256)
LAYOUT_ID NOT NULL NUMBER(38)
LIFE_CYCLE_ID NOT NULL NUMBER(38)
UNIX_GID NUMBER(38)
UNIX_UID NUMBER(38)
DEFAULT_DB_SERVER_ID NUMBER(38)
AUTH_OBJECT_ID NOT NULL NUMBER(38)
UPDATED_BY VARCHAR2(64)
UPDATED_AT DATE
CREATED_BY VARCHAR2(64)
CREATED_AT DATE

Nate wrote:

class Revision < ActiveRecord::Base
belongs_to :environment
belongs_to :source_revision,
:class_name => ‘Revision’,
:foreign_key => ‘source_revision_id’
end

In your Revision model are you making any assignments to an @environment
instance variable, or have you defined an “environment” attr_accessor?
If so, rename to avoid conflict with the belongs_to.


We develop, watch us RoR, in numbers too big to ignore.

Thanks - that’s exactly what it was. Deeply nested private method
(written by somebody else :-).

Cheers,
Nate

On 21 Oct 2008, at 18:44, Chris B. wrote:

end
Is there a way to do this and have it use the association? I need to

else
puts “No change in status” #Debugging
end
end
end

@status needs to be an association proxy, not the raw ProjectStatus
object. easiest way out is problably to alias_method the old status=
method so that you can call it easily from your status= method.

Fred

Frederick C. wrote:

@status needs to be an association proxy, not the raw ProjectStatus
object. easiest way out is problably to alias_method the old status=
method so that you can call it easily from your status= method.

Fred

Doesn’t alias_method and alias_method_chain only work from within a
module? This is in an ActiveRecord class.

Mark Reginald J. wrote:

Nate wrote:

class Revision < ActiveRecord::Base
belongs_to :environment
belongs_to :source_revision,
:class_name => ‘Revision’,
:foreign_key => ‘source_revision_id’
end

In your Revision model are you making any assignments to an @environment
instance variable, or have you defined an “environment” attr_accessor?
If so, rename to avoid conflict with the belongs_to.


We develop, watch us RoR, in numbers too big to ignore.

Is there a way to do this and have it use the association? I need to
override the assoc= method of a model to make sure the assignment
matches some predefined criteria. However, if I try to assign via
@assoc= I get the error message about an undefined target, and if I use
self.assoc= I wind up in an endless recursion until a stack overflow
occurs.

class Project < ActiveRecord::Base
belongs_to :status, :class_name => “ProjectStatus”,
:foreign_key => ‘status_code’

Updates the current project’s status unless the current

status is greater than the new status. Status’ are compared

using ProjectStatus::compare_status method The

new_project_status argument should be a ProjectStatus record

(i.e. ProjectStatus::SOME_STATUS)

def status= (new_project_status, override = false)
puts “Current status = #{@status}” #Debugging
if override or @status < new_project_status
puts “New status = #{new_project_status}” #Debugging
@status = new_project_status
else
puts “No change in status” #Debugging
end
end
end

class ProjectStatus < ActiveRecord::Base
has_many :project, :foreign_key => “status_code”

def > (status); compare_status(status, “>”); end
def >= (status); compare_status(status, “>=”); end
def < (status); compare_status(status, “<”); end
def <= (status); compare_status(status, “<=”); end

def self.find_by_code (code)
ProjectStatus.find(:first, :conditions => [‘code = ?’, code])
end

def to_s; self.status; end
def to_i; self.id; end

Setup some shortcuts i.e. ProjectStatus::SOME_STATUS

will return the status record for that code

def self.const_missing(sym)
if s = ProjectStatus.find_by_code(sym.to_s)
s
else
super
end
end

private

def compare_status (status, op)
eval self.order.to_s + op + status.order.to_s
end
end

Frederick C. wrote:

Classes are modules (in that Class is a subclass of Module) and there
is nothing special about ActiveRecord classes in that respect.

Fred

Oh, OK. I swear I had trouble using alias_method in a class once, but
I’ll give it another go.

Thanks!

On Oct 22, 1:58 am, Chris B. [email protected]
wrote:

Frederick C. wrote:

@status needs to be an association proxy, not the raw ProjectStatus
object. easiest way out is problably to alias_method the old status=
method so that you can call it easily from your status= method.

Fred

Doesn’t alias_method and alias_method_chain only work from within a
module? This is in an ActiveRecord class.

Classes are modules (in that Class is a subclass of Module) and there
is nothing special about ActiveRecord classes in that respect.

Fred