Acts_as_threaded - help?


#1

Hi, has anyone successfully used the acts_as_threaded plugin with
postgresql?

I’m using rails 1.0 and ruby 1.8.4 on linux.

Following the screencast on
http://www.railtie.net/articles/2006/02/05/rails-acts_as_threaded-plugin
,
I got to where we’re ready to create our first post, having made the
changes to controllers/posts_controller.rb, views/posts/_form.rhtml,
views/posts/show.rhtml, and models/post.rb as shown in the screencast.

When I submit the post I get an SQL error:
PGError: ERROR: null value in column “root_id” violates not-null
constraint:
INSERT INTO posts (“name”, “updated_at”, “body”, “depth”, “lft”,
“subject”, “root_id”, “parent_id”, “rgt”, “created_at”)
VALUES(‘Richard Nixon’, ‘2006-03-14 19:45:58’,
‘Erase tape number 2347!’, 0, 0, ‘Memo’, NULL, NULL, 0,
‘2006-03-14 19:43:00’)

We can see NULL values being provided for root_id and parent_id,
and I believe this to be incorrect. (I tried removing the NOT NULL
constraints, but got NoMethodError for nil exceptions further along.)
Note: The depth, lft, and rgt fields would have been NULL also, but I
set them to zero in the form manually before submitting the form.

This seems to be a key difference from the screencast. The
screencast shows the form already displaying default values of
zero for Depth, Lft, and Rgt:
http://tastyspleen.net/~billk/acts_as_threaded_post_defaults.png

Whereas in my app, these fields are blank:
http://tastyspleen.net/~billk/acts_as_threaded_post_nodefaults.png

Can anyone suggest any hints or ideas as to why the form in
the screencast would have default values pre-populated for some fields,
but my application presents the form with these fields uninitialized?

These are the files I’ve modified from the scaffold, with only the
very slight changes shown in the screencast:

http://cila-search.net/~billk/forum_060314/app/models/post.rb
http://cila-search.net/~billk/forum_060314/app/controllers/posts_controller.rb
http://cila-search.net/~billk/forum_060314/app/views/posts/_form.rhtml
http://cila-search.net/~billk/forum_060314/app/views/posts/show.rhtml

Thanks for any help, hints, suggestions, possibilities, etc. !

Regards,

Bill


#2

The fields are defined as default 0 in mysql.

Instead of using my acts_as_threaded plugin, try this code using the
default acts_as_nested set act in AR.

Stick this code in you threaded/nested_set model

HANDLE ACTS AS NESTED SET FUNCTIONALITY

acts_as_nested_set :scope => :root

def before_create
# Update the child object with its parents attrs
unless self[:parent_id].to_i.zero?
self[:depth] = parent[:depth] + 1
self[:root_id] = parent[:root_id]
end
end

def after_create
# Update the parent root_id with its id
if self[:parent_id].to_i.zero?
self[:root_id] = self[:id]
self.save
else
parent.add_child self
end
end

def parent
@parent ||= self.class.find(self[:parent_id])
end

And in your db definition:

root_id int
parent_id int default 0
lft int
rgt int
depth int default 0

When using it, just make sure child entries have their parent_id set
when saving and presto! everything works just like acts_as_threaded.

Good luck, I’ll blog about this at some point when my load lightens up.

Bob S.
http://www.railtie.net/


#3

From: “Bob S.” removed_email_address@domain.invalid

The fields are defined as default 0 in mysql.

Instead of using my acts_as_threaded plugin, try this code using the
default acts_as_nested set act in AR.

Stick this code in you threaded/nested_set model
[…]

Hi Bob, - Thanks !!!

Regards,

Bill


#4

Bob,

This lets you create a new child. How would you go about updating a
child
with a new parent?

Thanks

Dom

On 15 Mar 2006 07:13:18 -0000, Bob S.
removed_email_address@domain.invalid


#5

How can I “make sure child entries have their parent_id set when
saving?”
Is this done in the ‘views’ or the ‘controller’?

my current code snippets::

app/controllers::
def reply
@messages = Messages.new
if @messages.parent_id = Messages.new
flash[:notice] = ‘Your Reply was Posted.’
render :action => ‘new’
else
@messages = Messages.new(params[:messages])
end
end

app/views::

reply.rhtml
<%= start_form_tag :action => ‘reply’ %>
<%= render_partial “form” %>
<%= submit_tag " REPLY " %>
<%= end_form_tag %>

_form.rhtml

<%= text_field ‘messages’, ‘username’ %>
<%= text_field ‘messages’, ‘email’ %>
<%= text_field ‘messages’, ‘subject’ %>
<%= text_area ‘messages’, ‘message’ %>
<%= hidden_field ‘messages’, ‘id’ %>
<%= hidden_field ‘messages’, ‘root_id’ %>
<%= hidden_field ‘messages’, ‘parent_id’ %>
<%= hidden_field ‘messages’, ‘depth’ %>
<%= hidden_field ‘messages’, ‘Lft’ %>
<%= hidden_field ‘messages’, ‘Rgt’ %>

show.rhtml
<% for column in Messages.content_columns %>
<% end %>
On <%= @messages.created_on %>
<%= @messages.username %>
wrote: <%= @messages.message %>


#6

I am finding the answers in your tutorial

http://www.railtie.net/plugins/acts_as_threaded/threaded.swf

thanks,
Monica