Read_attribute mystery

I have the following 3 classes:

class User < ActiveRecord::Base
has_many(:project_roots)
end

class Project < ActiveRecord::Base
self.acts_as_tree(:order => “title”, :uniq=>true)
def user()
self.root.user()
end
end

class ProjectRoot < Project
self.belongs_to(:user)

def user()

read_attribute(:user)

end

end

and these 2 migrations:

class CreateProjects < ActiveRecord::Migration
def self.up
create_table :projects do |t|
t.column :type, :string # single-table inheritance

  # common attributes
  t.column :parent_id, :integer
  t.column :title, :string
  t.column :description, :text

  # attributes for type=ProjectRoot
  t.column :user_id, :integer
end

end
end

class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :name, :string
t.column :password_code, :string
t.column :password_salt, :string
end
end
end

First I uncomment out ProjectRoot#user, and then do this in a console:

u1=User.find_first
p1=ProjectRoot.new(:title=>‘p1’, :description=>‘p1’)
u1.project_roots<<p1
p1.user
=> nil

I put the comments back in (and bring up a new console, and again run
the above) and now correctly get this:

p1.user
=> #<User:0x4807bdc …>

  1. Why is read_attribute not working?

Furthermore, (with the comments left in) I proceed to do:

p2=Project.new(:title=>‘p2’, :description=>‘p2’)
p1.children<<p2
p2.root
=> #<ProjectRoot:0x47f4ed8 @attributes={“title”=>“p1”, …>

p2.user
=> #<User:0x47f1f94 …>

  1. Why don’t I get into an infinite loop with Project#user? (Actually
    this consideration was the very reason for implementing
    ProjectRoot#user.)

All help greatly appreciated.

Um, are you trying to get the user name for the project?

Why are you specifying a belongs_to and a read_attribute? There is no
attribute called user in the projects table.

Also you’re using parenthesis around everything! You don’t need to do
this!

has_many(:project_roots) can be written as has_many :project_roots

def user() can be written as def user

self.root.user() can be written as self.root.user

The has_many and belongs_to looks like it’s working as it should be,
assuming you only want one user to have many projects.

if you want many users to have many projects use
has_and_belongs_to_many.

On Dec 18, 2007 10:56 AM, Paul D. [email protected] wrote:

self.root.user()

 t.column :description, :text
 t.column :name, :string

p1=ProjectRoot.new(:title=>‘p1’, :description=>‘p1’)

  1. Why is read_attribute not working?
  2. Why don’t I get into an infinite loop with Project#user? (Actually
    this consideration was the very reason for implementing
    ProjectRoot#user.)

All help greatly appreciated.


Ryan B.
http://www.frozenplague.net

Ok thanks. I missed the boat with the read_attribute, but the basic
idea still stands – to avoid the infinite loop. I still don’t
understand why it’s not a problem. As far as the parenthesis, I know
all about them and use them because I don’t like sugar. And thanks
for the tip with the has_and_belongs_to_many.

  • PD

What infinite loop are you on about? Project already knows about its
user!

On Dec 18, 2007 11:30 AM, Paul D. [email protected] wrote:

self.root.user() can be written as self.root.user

class Project < ActiveRecord::Base

end

 # common attributes

class CreateUsers < ActiveRecord::Migration
First I uncomment out ProjectRoot#user, and then do this in a console:

p1.user
p2.user

  • Show quoted text -


Ryan B.
http://www.frozenplague.net

ProjectRoot is a subclass of Project. Project implements user as

def user
self.root.user
end

ProjectRoot inherits this implementation. In ProjectRoot, self.root
returns self, as shown in this console snippet:

p1=ProjectRoot.new(:title=>‘p1’, :description=>‘p1’)
p1.root.equal?(p1)
=> true

It’s as if ProjectRoot had this method for user:

def user
self.user
end

This is what I would call an infinite loop!

-PD

Project is a tree structure, with a ProjectRoot as the tree root.
User only knows about ProjectRoots. A (regular) Project asks its root
for the user. I understand what you are writing, but would still like
an answer regarding the infinite loop. Thanks

I still don’t get what you’re trying to do.

Are you trying to get ProjectRoot and Project to both have access to the
user? Which one of these models is user linked to? If it’s linked to
ProjectRoot you can, in User do this:

class User < ActiveRecord::Base
has_many :projects, :through => “ProjectRoot”
end

On Dec 18, 2007 12:03 PM, Paul D. [email protected] wrote:

p1.root.equal?(p1)
-PD

Um, are you trying to get the user name for the project?

On Dec 18, 2007 10:56 AM, Paul D. [email protected]

def user()

 t.column :title, :string

create_table :users do |t|

p1.user
p2.user
Ryan B.http://www.frozenplague.net-Hide quoted text -

  • Show quoted text -


Ryan B.http://www.frozenplague.net- Hide quoted text -

  • Show quoted text -


Ryan B.
http://www.frozenplague.net

Perhaps you’re looking for something like acts_as_tree?

On Dec 18, 2007 12:16 PM, Paul D. [email protected] wrote:

user? Which one of these models is user linked to? If it’s linked to

returns self, as shown in this console snippet:
This is what I would call an infinite loop!

Ok thanks. I missed the boat with the read_attribute, but the

Um, are you trying to get the user name for the project?

end

def user()

 t.column :type, :string # single-table inheritance

end

I put the comments back in (and bring up a new console, and

ProjectRoot#user.)

  • Show quoted text -


Ryan B.http://www.frozenplague.net- Hide quoted text -

  • Show quoted text -


Ryan B.
http://www.frozenplague.net

Exactly. To quote from my original post:

class Project < ActiveRecord::Base
self.acts_as_tree(:order => “title”, :uniq=>true)

-PD

Paul D. wrote:

Project is a tree structure, with a ProjectRoot as the tree root.
User only knows about ProjectRoots. A (regular) Project asks its root
for the user. I understand what you are writing, but would still like
an answer regarding the infinite loop. Thanks

Because the user method is automatically generated by ActiveRecord::Base
and overrides yours ?

If I’m right calling user on a child Project should return nil with your
code. Assuming I’m right, you’d have to use a different name for your
user method or your user_id column or define your user method after
AR::B generates its methods. IIRC you can do it in after_initialize.

Lionel

Then why do you have something called a ProjectRoot? This is unneeded.
Acts
as tree should know which was the initial project by being able to climb
“up” the tree until it finds the root, i.e. the only thing along that
chain
without a parent id.

On Dec 18, 2007 12:18 PM, Paul D. [email protected] wrote:

for the user. I understand what you are writing, but would still like

class User < ActiveRecord::Base

end
def user
user!
know
There

has_many(:project_roots) can be written as has_many

has_many(:project_roots)
self.belongs_to(:user)
create_table :projects do |t|
end
end
=> nil

  1. Why is read_attribute not working?
  • Show quoted text -


Ryan B.http://www.frozenplague.net- Hide quoted text -

  • Show quoted text -


Ryan B.
http://www.frozenplague.net

Thanks, but I have my reasons…
-PD

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs