Friday, February 22, 2008

Rails Forum Tutorial for Beginners (Part 1 of 3)

This is my first tutorial, so bear with me. I am writing it as if trying to teach someone brand new to rails what is going on. We are going to be creating a forum site in Ruby on Rails(2.0). I plan on this to be a several-part series, so keep coming back and checking for updates.

So here we go!



rails myforum -d mysql

This will create the project folder 'myforum' and force the database used to mysql(the newest version of rails default to sqlite3). All kinds of files and folders are created, but don't let them overwhelm you. Rails is an application framework, so by creating all this stuff it will force you to keep everything organized according to Rails' conventions.

Now, the general layout I decided on for the forums is this: The site will have multiple forums, each forums is going to have multiple topics, and each topic will have multiple replies. To get this going, lets try this:


cd myforum
ruby script/generate scaffold Forum name:string description:text


More files and directories are created, setting up migration files for the database, a model, a controller, and views for the Forum class. Lets analyze the command we just gave:
ruby script/generate - on a mac or on linux, it would be script/generate(I'm on windows). You will be using script/generate for a lot of things in rails, so get used to typing that one.
scaffold Forum - This tells rails that you want to generate a scaffold for the class 'Forum
name:string description:text - in the forums table that will be created, it will have 2 columns: name, and description. the :string and :text are the type of data, with string being a small 1 liner used for naming, and text being something that can be much longer. Moving on....


rake db:create
rake db:migrate


rake db:create will create your mySQL database for you (called myforum_development). rake db:migrate will create the table for the forum class.

Now lets fire up the server and see what we've got!

ruby script/server

And point your web browser(and you better not be using IE!) to http://localhost:3000


So the server is working fine, now go to http://localhost:3000/forums



If you click on New forum, it will give you a form with fields for Name and Description.





And then click back:




Thats right! With only 4 lines of code, rails was able to generate all of this! The scaffolding will create everything you need to Create, Read, Update, and Delete(CRUD).

Moving on, lets set things up so that rails will show the list of forums page by just going to http://localhost:3000, and get rid of that rails info page. Delete the file public/index.html, and then in config/routes.rb do this:

#In config/routes.rb

ActionController::Routing::Routes.draw do |map|
map.resources :forums
map.root :controller => 'forums', :action => 'index' # <-------add this line

..........
..........
end


So this is our first editing of a rails file. routes.rb is very important to the whole rails applications. They take a request for a URL and turn it into a request from a controller and an action. In this case, the line we added will take a request for the root(http://localhost:3000) and give us back the index action of the forums controller(which will list all the forums). Save, and again, point the browser to http://localhost:3000:




Great! Now, lets go ahead and generate scaffolding for our other 2 classes: Topics and Replies:


ruby script/generate scaffold Topic forum:references user:references subject:string body:text

ruby script/generate scaffold Reply topic:references user:references subject:string body:text

rake db:migrate

We have something new here. forum:references means that a topic will contain a foreign key to the forum it belongs to. It will also contain a foreign key for the user the posts it. Additionally, a reply will belong to a certain topic. And again, rake db:migrate will create the additional tables in the database. Don't worry about the User class yet, that part will be in a later tutorial when we add authentication.

If you go to http://localhost:3000/topics and http://localhost:3000/topics, you will see similar pages to the forum page that was created earlier.

Now that we have our scaffolding up, its time to take a look at some of the code that was generated and put it where we want it. First, lets go to /config/routes.rb and do a few things:


BEFORE:
#In config/routes.rb

ActionController::Routing::Routes.draw do |map|

map.resources :replies
map.resources :topics
map.resources :forums

map.root :controller => 'forums', :action => 'index'
...............
...............
end



AFTER:
#In config/routes.rb

ActionController::Routing::Routes.draw do |map|

map.resources :forums, :has_many => :topics
map.resources :topics, :has_many => :replies
map.resources :replies

map.root :controller => 'forums', :action => 'index'
...............
................
end


This sets up routing so that to view a specific post, you would go to a URL like: /forums/1/posts/3, and to see a reply /posts/1/replies/3.

Moving on, lets edit the files in /app/models/


#forum.rb

class Forum < ActiveRecord::Base
has_many :topics
has_many :replies, :through => :topics
end
------------------------------
#topic.rb

class Topic < ActiveRecord::Base
belongs_to :forum
belongs_to :user
has_many :replies
end
-------------------------------
#reply.rb

class Reply < ActiveRecord::Base
belongs_to :topic
belongs_to :user
end



All of that should make sense to you, just fleshing out some of the stuff we've already talked about.

Next, lets check out /app/controllers/topics_controller.rb. Add these lines to it:


before_filter :load_forum

def load_forum
@forum = Forum.find(params[:forum_id])
end


before_filter :load_forum will cause the load_forum method to be called anytime the topics controller is accessed.


Now, in the index function, change:
@topics = Topic.find(:all)

to
@topics = @forum.topics


Now change every instance of:
@topic = Topic.find(params[:id])

to
@topic = @forum.topics.find(params[:id])

and in the new function:
@topic = Topic.new

to
@topic = @forum.topics.build


Change the create function from:

def create
@topic = Topic.new(params[:topic])

respond_to do |format|
if @topic.save
flash[:notice] = 'Topic was successfully created.'
format.html { redirect_to(@topic) }
format.xml { render :xml => @topic, :status => :created, :location => @topic }
else
format.html { render :action => "new" }
format.xml { render :xml => @topic.errors, :status => :unprocessable_entity }
end
end
end

to

def create
@topic = @forum.topics.build(params[:topic])

respond_to do |format|
if @topic.save
flash[:notice] = 'Topic was successfully created.'
format.html { redirect_to(@forum) }
format.xml { render :xml => @topic, :status => :created, :location => @topic }
else
format.html { render :action => "new" }
format.xml { render :xml => @topic.errors, :status => :unprocessable_entity }
end
end
end


In update, change the line:

format.html { redirect_to(@topic) }

to

format.html { redirect_to(@forum) }

and finally, in destroy, change the line:

format.html { redirect_to(topics_url) }

to

format.html { redirect_to(forum_topics_url(@forum)) }


Alright, lets take a look at all that we just did. With the code that was generated by the scaffold, Rails did not take into account the fact that we need to retrieve our topic classes by a foreign key(forum_id). The majority of the changes were in setting that up correctly. The other changes were in the redirect_to function calls. Whenever I create, update, or destroy a topic, I want it to redirect back to the forum I was on instead of going back to the topic page automatically assigned.

Now, when we go to look at a specific forum, we want it to list out not just the forum title and description, but all the topics associated with that forum. Open up /app/views/forums/show.html.erb


<p>
<b>Name:</b>
<%=h @forum.name %>;
</p>

<p>
<b>Description:</b>
<%=h @forum.description %>
</p>


<%= link_to 'Edit', edit_forum_path(@forum) %> |
<%= link_to 'Back', forums_path %>


Since this is our first look at a view, let go over it a bit.

The <% tags work kind of like <?php tags. They switch out of normal HTML markup to ruby code. Inside these tags are where the magic happens. So a tag with just <% will not display anything, they are useful for doing things like loops. A tag with <%= will output the result into the HTML markup. So the line <%=h @forum.name %> will display the name of the forum. The lowercase 'h' is there escape HTML characters in output.
Change the file to this:


<p>
<b>Forum:</b>
<%=h @forum.name %> - <%=h @forum.description %>
</p>

<% unless @forum.topics.empty? %>
<h2>Topics</h2>
<% @forum.topics.each do |topic| %>
<b><%= link_to topic.subject, [@forum, topic] %></b><br />
<% end %>
<% end %>

<%= link_to 'Edit', edit_forum_path(@forum) %> |
<%= link_to 'Back', forums_path %>



Now one more thing; I want to have a 'Create New Topic' form at the bottom of the page. First, lets take a look at /app/views/topics/new.html.erb and /app/views/topics/edit.html.erb. These 2 files are nearly identical. This is a good time to use the DRY(Don't Repeat Yourself) that Rails is big on. Lets create a new file called _topic.html.erb in the /app/views/topics/ folder and put the following code into it:

<% form_for([@forum, @topic]) do |f| %>
<p>
<b>Subject</b><br />
<%= f.text_field :subject %>
</p>

<p>
<b>Body</b><br />
<%= f.text_area :body %>
</p>

<p>
<%= f.submit button_name %>
</p>
<% end %>

And then change edit.html.erb and new.html.erb to look like this:

#edit.html.erb

<h1>Editing topic</h1>

<%= error_messages_for :topic %>

<%= render :partial => @topic, :locals => { :button_name => "Submit" } %>

<%= link_to 'Show', [@forum, @topic] %> |
<%= link_to 'Back', topics_path %>

----------------------------
#new.html.erb

<h1>New topic</h1>

<%= error_messages_for :topic %>

<%= render :partial => @topic, :locals => { :button_name => "Create" } %>

<%= link_to 'Back', topics_path %>


That cleaned up a good bit of code. Since the only real difference in the 2 forms for those pages was the button name, we created what is called a partial in the file _topic.html.erb, and then rendered the partial in new.html.erb and edit.html.erb, passing in the value of the button name. And now, we can also re-use the partial in /app/views/forums/show.html.erb

Change the file to look like this:


<p>
<b>Forum:</b>
<%=h @forum.name %> - <%=h @forum.description %>
</p>

<% unless @forum.topics.empty? %>
<h2>Topics</h2>
<% @forum.topics.each do |topic| %>
<b><%= link_to topic.subject, [@forum, topic] %></b><br />
<% end %>
<% end %>

<h2>New Post</h2>
<%= render :partial => @topic = Topic.new, :locals => { :button_name => 'Create' } %>

<%= link_to 'Edit', edit_forum_path(@forum) %> |
<%= link_to 'Back', forums_path %>


One more thing, open up /app/views/topics/show.html.erb and remove this part:

<p>
<b>User:</b>
<%=h @topic.user %>
</p>

Since we haven't implemented the authentication yet.

And change the line:
<%=h @topic.forum %>

to
<%=h @forum.name %>

And then change:
<%= link_to 'Back', topics_path %>

to
<%= link_to 'Back', forum_path(@forum) %>

Save everything, fire up the server, and head back to http://localhost:3000
ruby script/server



Click Show



And there we go! You can add a new post, and then click on it to show it.

So far in the tutorial, we have generated scaffolding for 3 classes(forum, topic, reply), set up the nested routing for topics to be inside forums, and replies to be inside topics, and modified the controllers and view for forum and topic to work like we need it to.

I've decided this will be a 3-part tutorial. The next part will be to get the Replies working(it will be very similar to what we did with nesting topics inside forums) by modifying the views for topics, and the views and controllers for replies. The third part will be to set up Authentication and Admin priveleges.

Let me know what you think, or if you have any questions. And tell your friends.

See you next time!

56 comments:

  1. Great tutorial!
    I like the topics covered here.

    I had some issues, but I think I may have skipped a few steps. I will retry the tutorial again...

    Thanks!

    ReplyDelete
  2. Thanks for commenting, and congratulations on being the first one. Nice to know some of this work I'm putting into the blog is helping someone!

    If you have any suggestions on how I can better organize the tutorial, let me know.

    ReplyDelete
  3. Thanks again for this great tutorial. This is the only beginners tutorial (that I have seen) which covers related tables e.g. has_many e.t.c. Thank you for taking on that challenge.

    One minor correction, the lower case h is not to protect against SQL injection, it is to escape html characters in the output.

    A slightly bigger problem, I am getting an error when I try to edit a topic. I click on a topic, then if I click back or edit I get an error. In both cases (edit and back) I get the following error:
    "Couldn't find Forum without an ID"

    The database seems to be populated correctly. Is this meant to be working? Have I made a mistake?

    I am very new to Rails, but I think there is a problem with the app\views\topics\show.html.erb file. I do not think the links are being created correctly.

    What do you think?

    Thanks for the help
    I will recommend your blog on mine :)

    ReplyDelete
  4. I will have to check on the code tomorrow, I don't have it on this computer. Looking through the tutorial, I don't see where I told you to edit the links at the bottom of topics/show.html.erb...I may have been waiting for the next part of the tutorial.

    Without looking at the code....my guess for the Edit link would be:

    <%= link_to 'Edit', [:edit, @forum, @topic] %>

    or something similar. Let me know and I will get back to you tomorrow.

    And thanks for the recommendation!

    ReplyDelete
  5. Thanks for the fast reply.
    I tried changing it, but that ended up making a new topic instead of editing. I think it is best if you have a look at it on your side.

    I am looking forward to the next tutorial!

    ReplyDelete
  6. I found the problem, it was in the topics_controller.rb

    In the edit function I had the line:
    @topic = @forum.topics.build(params[:topic])

    So the reference to a topic being passed was a NEW topic(.build). Change it to:
    @topic = @forum.topics.find(params[:id])

    And everything works. Will update this on the tutorial after lunch. Thanks for helping me find the bug.

    ReplyDelete
  7. This tutorial has been very help. Thank you for putting it together.

    I have one question, when I click on the show link and then try to submit the topic form, I receive the following message:

    ActiveRecord::RecordNotFound in TopicsController#create
    Couldn't find Account without an ID

    It appears that when I submit the form that the foreign key isn't being sent with the rest of the data. I've been all through the steps to double check what I've done but I can't seem to find the problem.

    Could you give quick summary as to how the foreign key is submitted to the database when a new record is created? Should there be a hidden field containing the key or is it handled in another way?

    Thank you!

    ReplyDelete
  8. Hmm...it should be taken care of. In your topics controller, create def the first line should be

    @topic = @forum.topics.build(params[:topic])

    And in _topic.html.erb, the first line should be

    <% form_for([@forum, @topic]) do |f| %>

    Those are the 2 places I would look.

    I was just able to recreate your error by changing the first line in _topic.html.erb to
    <% form_for(@topic) do |f| %>, so if you change that line to <% form_for([@forum, @topic]) do |f| %> it should fix you up.

    ReplyDelete
  9. Thank you. That is exactly where my problem was.

    Another thing I'm trying to figure out is, how would I place the "new topic" code on another page. Instead of showing the form on the forum page, I'm trying to create a link called "new topic" which would go to a separate web page. I can't seem to figure out how to send the foreign key again.

    Thank you!

    ReplyDelete
  10. Something along the lines of:
    <%= link_to 'New Topic', new_forum_topic_path(@forum) %>

    ReplyDelete
  11. I notice once viewing a topic it wouldn't take you back to the forum page.

    file show.html.erb in topics

    "link_to 'Back', topic_url"

    to

    "link_to 'Back', forum_url"

    fixed the issue havent read over part 2 maybe you coverd it then i figured it would fit more in the first part :D blah couldnt figure out the code blocks too hehe

    ReplyDelete
  12. Thanks for the comment, I'll get that added into the tutorial soon. I'm sure there are a few small things that don't work as they should(see above comments), let me know if you come across anything else.

    ReplyDelete
  13. Hi,

    Thanks for the great tutorial, I learned a lot from it :). I'm just starting out to try and learn rails and other tutorials have thrown me because of the way rails has developed so fast, the tutorials have become out of date. Your is the first I have seen dealing with rails 2.0.x and you have presented it very well please keep up the good work. I'm just about to go try the second instalment

    A couple of very minor points:

    Would it be possible to annotate the tutorial with say step numbers when changing subject material? I find this a major help in understanding logical boundaries.

    Also by no fault of yours I actually found your tutorial via IRC were you posted the link. My IRC client is konversation and it automatically opened the link in konqueror. Everything looked good so I thought nothing of it until I got much further down into it and konqueror was badly rendering your screen snapshots leaving out important aspects. I reloaded it in firefox and saw the major differences. You might want to put a note to this effect at the start of the tutorial.

    Once again thanks very much !!

    ReplyDelete
  14. petert - thanks for the suggestions, I had thought about breaking the individual tutorials into sections. The screenshots aren't very good quality, but most of them are links that lead to the original image.

    ReplyDelete
  15. Thanks very much for this. I had previously found it very difficult as a beginner to reconcile what the rails 1.2 books were explaining with 2.0. These tutorials are really excellent.

    I post back with any comments when I've gone through all the tutorials.

    one very minor thing (I'm being really pick here), Forum, Topic etc are classes not objects. Each instance of this class created in localhost:3000/controller is an object with the instance variables defined within the scaffold.

    ReplyDelete
  16. Hi,
    This is a great tutorial. Thanks to you for posting this.
    I am waiting for the tutorial act_as_state_machine. I want to develop one cms application. In that I want to give the work flow.
    So, please post that tutorial ASAp.

    Thank you,
    ssrinivas

    ReplyDelete
  17. srinivas:

    Part 3 covers using restful_authentication together with acts_as_state_machine - but the state machine part isn't used a whole lot. I hadn't planned on writing a tutorial for acts_as_state_machine, but I might just do it now. I've been asked at work about doing some workflow stuff too, so it seems like it might be beneficial to me as well to learn acts_as_state_machine better. Stay tuned!

    ReplyDelete
  18. Great tutorial!

    Having difficulty with viewing a topic. I can see the link but get an error stating i have a nil object. Here's the line of code in the forum/show.html.erb
    link_to topic.subject, [@forum, topic]

    Thanks

    ReplyDelete
  19. Hi all...
    For those of you having routing problems you are welcome to read the tutorial on my blog. Hope it helps, thanks...

    ReplyDelete
  20. I found my mistake. Missing the u in forum.

    ReplyDelete
  21. The code for your *.html.erb files isn't showing up anymore. I checked the source and it looks like your blogging engine is printing out a bunch of blank lines.

    ReplyDelete
  22. Nevermind... I just looked at the actual source, instead of Safari's "inspect element" source, and it looks like it's there. Must be an issue with Safari.

    ReplyDelete
  23. This comment has been removed by the author.

    ReplyDelete
  24. When clicking show when in /forums, I get this error:

    NoMethodError in Forums#show

    Showing topics/_topic.html.erb where line #1 raised:

    undefined method `new_record?' for #Array:0x532a3e8

    I'm not really sure what's causing it?

    ReplyDelete
  25. pastie me the error, the code in your forums controller, views/forum/show.html.erb and views/topics/_topic.html.erb...

    ReplyDelete
  26. Error code screenshot
    _topic screenshot
    show screenshot


    class ForumsController < ApplicationController

    before_filter(:only => [ :new, :edit, :destroy, :update, :create ]) { |c| c.role_required 'editor' }

    # GET /forums
    # GET /forums.xml
    def index
    @forums = Forum.find(:all)

    respond_to do |format|
    format.html # index.html.erb
    format.xml { render :xml => @forums }
    end
    end

    # GET /forums/1
    # GET /forums/1.xml
    def show
    @forum = Forum.find(params[:id])

    respond_to do |format|
    format.html # show.html.erb
    format.xml { render :xml => @forum }
    end
    end

    # GET /forums/new
    # GET /forums/new.xml
    def new
    @forum = Forum.new

    respond_to do |format|
    format.html # new.html.erb
    format.xml { render :xml => @forum }
    end
    end

    # GET /forums/1/edit
    def edit
    @forum = Forum.find(params[:id])
    end

    # POST /forums
    # POST /forums.xml
    def create
    @forum = Forum.new(params[:forum])

    respond_to do |format|
    if @forum.save
    flash[:notice] = 'Forum was successfully created.'
    format.html { redirect_to(@forum) }
    format.xml { render :xml => @forum, :status => :created, :location => @forum }
    else
    format.html { render :action => "new" }
    format.xml { render :xml => @forum.errors, :status => :unprocessable_entity }
    end
    end
    end

    # PUT /forums/1
    # PUT /forums/1.xml
    def update
    @forum = Forum.find(params[:id])

    respond_to do |format|
    if @forum.update_attributes(params[:forum])
    flash[:notice] = 'Forum was successfully updated.'
    format.html { redirect_to(@forum) }
    format.xml { head :ok }
    else
    format.html { render :action => "edit" }
    format.xml { render :xml => @forum.errors, :status => :unprocessable_entity }
    end
    end
    end

    # DELETE /forums/1
    # DELETE /forums/1.xml
    def destroy
    @forum = Forum.find(params[:id])
    @forum.destroy

    respond_to do |format|
    format.html { redirect_to(forums_url) }
    format.xml { head :ok }
    end
    end
    end

    ReplyDelete
  27. Matt-
    I meant...use www.pastie.org to show me the files...go there, copy in the code for those 3 files, and then post the link that it gives you here, so I can go there and check it out.

    And photobucket is blocked from me here at work, so the screenshots didn't work.

    ReplyDelete
  28. http://www.pastie.org/180709 - Error
    http://www.pastie.org/180711 - _topic.html.erb
    http://www.pastie.org/180712 - show.html.erb
    http://www.pastie.org/180713 - forums_controller.rb

    ReplyDelete
  29. Great tutorial, looking forward to getting into parts 2 and 3.

    I have a problem with the topics/show.html.erb file... I get a nil.subject error when rails tries to evaluate

    @topic.subject

    I have the before_filter in the controller that should be loading the @forum and @topic objects, what else am I missing?

    Thanks again.

    ReplyDelete
  30. Matt: The problem is here:


    vendor/plugins/simply_helpful/lib/simply_helpful/form_helper_extensions.rb:5:in `form_for'


    Uninstall the simply_helpful plugin and you will get it runining!

    ReplyDelete
  31. (this is the error undefined method `-@' for Proc:0xb7a3e0b4>)

    can you please help me? i this occour during the loading of the page.

    ReplyDelete
  32. i have a problem in new forums. nothing come out in the page? the discriprion and the name are not there and the button too.

    ReplyDelete
  33. Thanks for this tutorial.
    Of minor importance, I noticed that after
    "Don't worry about the User class yet, that part will be in a later tutorial when we add authentication."
    it reads
    "If you go to http://localhost:3000/topics and http://localhost:3000/topics, you will see similar pages to the forum page that was created earlier."
    but should be
    "If you go to http://localhost:3000/topics and http://localhost:3000/replies, you will see similar pages to the forum page that was created earlier."

    More frustratiingly, I too was getting "ActiveRecord::RecordNotFound in TopicsController#edit
    Couldn't find Forum without an ID" errors until I changed
    link_to 'Edit', edit_topic_path(@topic)
    to
    link_to 'Edit', [:edit, @forum, @topic]
    as noted in the comments, but not changed in the tutorial itself.

    Then in
    app/view/topics/edit.html.erb
    I changed
    link_to 'Back', topics_path
    to
    link_to 'Back', [@forum, @topic]
    and
    link_to 'Back', forum_topic_path(@topic)
    (both seem to work out to the same effect)
    But I am still having problems getting the edit link to work for all topics except where the id is "1".

    I'm still an OOP, MCV, Rails newbie, any ideas?

    ReplyDelete
  34. While searching for various error messages, I was led to the edge of the routing abyss. It seems that by "fixing" the broken back links, I broke the previously working edit links. It may take me a while to digest the workings of Parameter Expiration and not make a mess of the path parameter hashing, but this tutorial, if not an A+, is definately an A. I've learned a lot about Rails and MCV even with my Procedural Thinking handicap.

    ReplyDelete
  35. Hi Mittineague

    re: "Couldn't find Forum without an ID" issue.

    I resolved this issue with the following change:

    In app/views/topics/show.html.erb

    change:
    link_to 'Edit', edit_topic_path(@topic)

    to:
    link_to 'Edit', edit_forum_topic_path(@forum, @topic)

    Which will provide you with that missing Forum ID.

    I hope this helps.

    Regards

    Walter

    ReplyDelete
  36. In topics\edit.html.erb I have:

    link_to 'Show', forum_topic_path(@forum, @topic)

    link_to 'Back', forum_path(@forum)

    This makes the "Show" link display the topic, and the "Back" link takes you to the forum topic listing.

    This seems to match the intent of the Forum edit page as well.

    ReplyDelete
  37. when I at this page:http://localhost:3000/forums/1,and try to create a new post after clicked the "Create" button, I will get this error:
    ActiveRecord::RecordNotFound in TopicsController#show
    Couldn't find Forum without an ID.
    The url now is:
    http://localhost:3000/topics/7.

    Could anyone give me some suggestion?

    Thanks in advance.

    ---Leo

    ReplyDelete
  38. Good work !
    but... how i can destroy topics ?

    No route matches "/forums/1/topics/destroy/3" with {:method=>:get}

    Thanks in advance.

    ReplyDelete
  39. @foo-

    it shouldn't be asking for delete page with :get, it should be :delete (RESTful).

    ReplyDelete
  40. 'One more thing, open up /app/views/topics/show.html.erb and remove this part:'

    but i can not see the next two changes in show.html.erb from your page

    ReplyDelete
  41. Does any one know where I might find an example to show how to do teh following. (Extensive searching has failed to find one.)

    I have three db tables A, B and C. A has a reference to B and B has a reference to C. I want to set up the reference to C in business logic. It is setting the reference to C that I can't do and it must be very simple I'm sure.

    I have
    In the model for B:
    has_one :C
    In the create method of the controller for B:
    @x = params[:b]
    @x.update({"c_id" => 1})
    @b = a.b.build(@x)

    but get an association type mismatch for C.

    ReplyDelete
  42. I have some problems, too, trying to edit a topic.
    Clicking on the "Edit" link I only can see an exception:

    Couldn't find Forum without an ID

    Well... The url of the show is:

    http://localhost:3000/forums/1/topics/1

    but the url of the Edit page is:
    http://localhost:3000/topics/1/edit

    There seems to miss the /forums/1/ part, right?

    Therefore I think I have to edit the edit-link in (topic)show.html.erb, right?

    link_to 'Edit', edit_topic_path(@topic)

    That is the actual link. Do I have to change it, being able to display the edit page?

    ReplyDelete
  43. Now I tried some things and fixed this bug by changing

    link_to 'Edit', edit_topic_path(@topic)

    to

    link_to 'Edit', forum_path(@forum) + edit_topic_path(@topic)

    But there is another bug being on the edit-topic page. The "back" link links to localhost:3000/topics

    I "fixed" it by changing the link on the edit page to

    link_to 'Back', [@forum, @topic]

    (same as show-link).

    I don't think this being a comfortable way of fixing this bugs, but I am still a noob on ror.
    Maybe someone can tell me how to fix it real.

    THX

    ReplyDelete
  44. Help, after I create a forum topic.. and hit create.. I go this error. I don't know how to fix it

    ActionView::MissingTemplate in Forums#show

    Showing app/views/forums/show.html.erb where line #15 raised:

    ReplyDelete
  45. Nevermind, I got it work.. woohoo

    ReplyDelete
  46. Hi !

    if i create a topic anf after it i want to edit it .. i get this error message

    Couldn't find Forum without an ID
    usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1567:in `find_from_ids'
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:616:in `find'
    /home/laces/forumom/app/controllers/topics_controller.rb:6:in `load_forum'

    Could anyone help me ? :)

    ReplyDelete
  47. Laszlo I've got the same problem...

    Did you fixed it?

    ReplyDelete
  48. I keep getting this at the end when I visit Localhost, any ideas? I'm pretty new to Rails to any help would be hot. Thanks!

    NameError in ForumsController#index

    undefined local variable or method `topics' for #

    RAILS_ROOT: C:/InstantRails/rails_apps/myforum

    C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1959:in `method_missing'
    C:/InstantRails/rails_apps/myforum/app/models/forum.rb:3
    C:/InstantRails/rails_apps/myforum/app/controllers/forums_controller.rb:5:in `index'

    Response

    Headers:

    {"Content-Type"=>"",
    "Cache-Control"=>"no-cache"}

    ReplyDelete
  49. In forum.rb do you have

    has_many :topics

    my first guess... hth

    ReplyDelete
  50. hello everyone, i just started working this, i am new in rails so i faced problem at the first stage lol
    let me know why can't i run this command
    script/generate scaffold Forum name:string description:text

    it shows error stating it already exists

    Thank you
    Noorin
    here is my email address
    noorin.khwaja@yahoo.com
    you can respond me here please
    thanks a lot

    ReplyDelete
  51. The following is an error I am getting:

    ActiveRecord::RecordNotFound in TopicsController#index

    Couldn't find Forum without an ID


    Any ideas? Thanks for the great tutorial!

    ReplyDelete
  52. To my mind one and all ought to look at this.

    ReplyDelete
  53. Seems like a really great tutorial. I'm just having a slight issue when posting a topic:

    undefined method `forum_topics_path' for #<#:0x38b04d0>

    Any ideas? It seems to be a problem with the line:

    <% form_for([@forum, @topic]) do |f| %>

    ReplyDelete