A simple forum in rails

I’ve to make a simple forum for my app.
The idea was to have:
Forum -has many < Forum_subjects -has many< posts

Now I’ve made a form in which the user enters the subject and the
first post, it was easy to add the subject to the forum :

params[:forum_subject][:forum_if] = 1 unless params[:forum_subject]
[:forum_id]
forum = Forum.find_by_id(params[:forum_subject][:forum_id])
@forum_subject = ForumSubject.new(params[:forum_subject])
if @forum_subject.save
forum.forum_subjects << @forum_subject
redirect_to :controller=>:forum, :action=>:list

end

end

I dont really know how to add a new post to this at the same time
I could assume to do that this way:

  • create new forum subject
  • get the last insert_id of the forum_subject
  • add new post to the subject
    The thing is I cant find the way to get the last insert_id (for
    finding the subject)

I guess there is another way of doing this, but I lack skill in
rails…

Forum:

has_many :subjects
has_many :posts, :through => :subjects

Subject:

belongs_to :forum
has_many :posts

Posts

belongs_to :subject

Don’t call them forum_subjects as that is violating the DRY (Don’t
Repeat
Yourself) principle.

params[:forum_subject][:forum_id] = 1 unless
params[:forum_subject][:forum_id]

Any reason for this? What if the first forum gets deleted?

forum = Forum.find_by_id(params[:forum_subject][:forum_id])

Instead of using find_by_id just use find, that is unless you want to
return
nil rather than an ActiveRecord::RecordNotFound exception (which should
never occur unless the user does something wrong)

@forum_subject = ForumSubject.new(params[:forum_subject])

@subject = forum.subjects.create!(params[:subject]) change in your form,
forum_subject to just subject, as I have done in the models.

add new post to the subject
@post = @subject.posts.create!(params[:post])

I also recommend using restful routing as it saves a lot of effort, for
example having to put forum_id into the form for the subject.

OK, Thank you very much.
I’ll get right on it after work :slight_smile:

On Mon, 11 Feb 2008 11:43:15 -0800, Adam wrote:

I dont really know how to add a new post to this at the same time I
could assume to do that this way:

  • create new forum subject
  • get the last insert_id of the forum_subject - add new post to the
    subject
    The thing is I cant find the way to get the last insert_id (for finding
    the subject)

What’s the model for your posts? Post? Do you have a controller
specific, a default one, for that controller?

-Thufir

Adam, if you’re still looking for some help I’ll be glad to help you
out,
add me as [email protected] on MSN if you have it, or on
googletalk.
Alternatively you can shoot me an email.

Right now i’ve folowed the tutorial, i’m stuck @ adding new topic and
the first post at the same time.
I’ll post the code later, tired at the time…

I guess what I’m doing right now is pretty simple but after a days
work it can be hard to figure it out.

I did a pretty simple form for topic and the post, like in a usual
forum the user can create a topic and add the first post.
Here’s the short version of the form.

<%form_for @topic do |f| %>
<%= f.hidden_field :user_id, :value=>session[:user_id] %>
<%= f.hidden_field :forum_id, :value=>@forum%>
<%= render :partial=>‘topics/form’,:locals=>{:f=>f} %>
<%fields_for @post do |p| %>

<%= p.text_field :subject,:size=>100%> <%= p.text_area :body %> <%end %> <%end %>

in the address bar before sending i’ve got host/forums/2/topics/new.

def create
@forum = Forum.new params[:forum_id]
@topic = Topic.new params[:topic]
@forum.topics << @topic

@post = Post.new params[:post]
@topic.save!
@post.save!
@topic << @post
 redirect_to forum_path(@topic.forum_id)

rescue ActiveRecord::RecordInvalid
render :action => :new
end

In the above part i’m doing something wrong cause i get a error
topic_id cannot be null …

and when i change Post.new params[:topic][post]
i get a validation error saying that body of the post cannot be null
and a redirection to /topics

So i guess the solution is pretty simple in here , but i lack skills,
I’m working on them thought :slight_smile:

You shouldn’t need to pass in user_id and forum_id as hidden fields, as
user_id should be stored as a session variable (session[:user]) and
forum_id
should come from the URL.

@forum = Forum.find(params[:forum_id])
@topic = @forum.topics.build(params[:topic])
@topic.posts.build(params[:post])
@forum.save!

That should do it.

On Wed, Mar 12, 2008 at 4:35 AM, Adam [email protected] wrote:

<%= f.hidden_field :forum_id, :value=>@forum%>

rescue ActiveRecord::RecordInvalid
So i guess the solution is pretty simple in here , but i lack skills,
I’m working on them thought :slight_smile:

On 11 Mar, 13:08, “Ryan B. (Radar)” [email protected] wrote:

Adam, if you’re still looking for some help I’ll be glad to help you
out,
add me as [email protected] on MSN if you have it, or on
googletalk.
Alternatively you can shoot me an email.


Ryan B.

Feel free to add me to MSN and/or GTalk as this email.

I dont really know why but in the version above the forum_id isn’t
passed within the url
i get a Couldn’t find Forum without an ID error.

What’s the URL look like? It needs to have the forum_id in there, so
like
/forums/1/topics should be the URL.

On Thu, Mar 13, 2008 at 4:17 AM, Adam [email protected] wrote:

<%= render :partial=>‘topics/form’,:locals=>{:f=>f} %>
def create
render :action => :new
I’m working on them thought :slight_smile:
Feel free to add me to MSN and/or GTalk as this email.


Ryan B.

Feel free to add me to MSN and/or GTalk as this email.

To just topics? That’s rather interesting. That might mean that in your
new
action for your topic you’re not doing either:

@topic = Topic.new(:forum_id => params[:forum_id])

or
#this code I would move into a private method called find_forum
@forum = Forum.find(params[:forum_id])
@topic = @forum.topics.build

If you’re doing just Topic.new I think it’ll just redirect to /topics,
but
if you do it either of the ways I specified it should go to
/forums/2/topics
On Thu, Mar 13, 2008 at 6:51 PM, Adam [email protected] wrote:

forum_id

<%= render :partial=>‘topics/form’,:locals=>{:f=>f} %>

rescue ActiveRecord::RecordInvalid

googletalk.


Ryan B.

Feel free to add me to MSN and/or GTalk as this email.

Yes the url looks like that forums/1/topics/new, after sending it it
changes to /topics and then throws an error

Putting the forum aside I was trying to make a faq, type thing for my
project also using rest
so i went to the config/routes.rb typed
map.resources :subject, :has_many=>:faqs
map.resources :faqs

And when i’m trying to add a new faq to existing subject via
subjects/2/faqs/new
And when i’m sending the form it’s redirected to /faqs with the same
error message :confused:

Ok resolved the address part the form_for method needs to look like
this
form_for[@subject,@faq] this is similar for the forum.

I’ll give the full code (after the modifications) cause I just don’t
know what to do anymore I’m getting redirected to /topics with the
message Couldn't find Forum without an ID

here’s the view:

<%= error_messages_for :topic %>
<%= error_messages_for :post %>

<%form_for @topic do |f| %>
<%= render :partial=>‘topics/form’,:locals=>{:f=>f} %>
<%fields_for @post do |p| %>

<%= render :partial=>'posts/form',:locals=>{:p=>p} %> <%end %> <%= f.submit :create %> <%end %>

the controller:
class TopicsController < ApplicationController
before_filter :user_logged_in?
layout :switch_layout
def index
@topics = @forum.topics
end

def new
@forum = Forum.find params[:forum_id]
@topic =
Topic.new :forum_id=>params[:forum_id], :user_id=>session[:user_id]
@post = Post.new
end

def create
@forum = Forum.find(params[:forum_id])
@topic = @forum.topics.build(params[:topic])
@topic.posts.build(params[:post])
@forum.save!

flash[:notice] = 'Created new topic' if @topic.save!
redirect_to forums_path

rescue ActiveRecord::RecordInvalid
render :action => :new
end

def edit
@topic = Topic.find params[:id]
end

def update
@topic = Topic.find params[:id]
if @topic.update_attributes params[:topic]
flash[:notice] = “Changed #{@topic.name}”
redirect_to forum_path(@topic.forum_id)
end
rescue ActiveRecord::RecordInvalid
render :action => :edit
end

def destroy
topic =Topic.find params[:id]
if topic.destroy
flash[:notice] = “topic: #{topic.name} was deleted”
end
redirect_to forum_path(topic.forum_id)
end

def show
@posts = Topic.find(params[:id]).posts
end
end