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.

http://frozenplague.net/2008/01/06/restful-routing-an-overview/

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

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

-Thufir

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

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

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| %> <fieldset class="alt">   <%= p.text_field :subject,:size=>100%>   <%= p.text_area :body %> </fieldset> <%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.

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.

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

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

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| %> <fieldset class="alt">   <%= render :partial=>'posts/form',:locals=>{:p=>p} %> </fieldset> <%end %> <fieldset id="submit">     <%= f.submit :create %> </fieldset> <%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

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.