2

I'm having general structural issues with Rails 3 and the new routes.rb is getting me a bit confused. Thanks for any help or guidance.

I have a forum application with nested resources. There are sections, topics, and replies. The routes.rb structure looks like this:

resources :sections do
   resources :topics do
     resources :replies
   end
end

My section.rb:

  has_many :topics
  has_many :replies, :through => :topics

My topic.rb:

  belongs_to :section
  has_many :replies

My reply.rb:

  belongs_to :topic

And this is working wonderfully. Now here's where I'm confused.

I added a user controller using Devise, and have a working username login/logout system. I'm trying to connect the 'current_user' with replies and topics. I think I have a good idea on how to fix the models, but I'm very confused with what to do in the routes.rb file.

For user.rb, I believe I need to add "has_many :topics" and "has_many :replies, :through => :topics". And then In my topics I need to add "belongs_to :user". I believe reply.rb remains the same?

As for the routes.rb I'm kind of stumped. If I edit the routes and add users to it, I would get a path like sectionid/username/topicid/ but I don't necessarily need to store a username in a route like that. So do I nest user in-between sections and topics or can I leave user out of the routes.rb file.

a3uge
  • 417
  • 4
  • 14

1 Answers1

2

You can leave the users out of the path. Just include the devise_for :users on top of your routes without including it in your resources block.

A user has many topics and has many replies. Both topics and replies belong to a user.

There are more changes in your controllers needed. You need to add a before_filter to check if users are authenticated and in addition changes in most of your controller methods to check if users are not only authenticated but also authorized, e.g. for an edit lookup you do current_user.replies.... . You can read more on that here (my own page): http://www.communityguides.eu/articles/4.

Markus Proske
  • 3,356
  • 3
  • 24
  • 32
  • So in my topics controller, when I create, where do I set its user? Do I do a before_filter and have a method that goes '@user = current_user' and will that save the user when I create a new topic? Or do I need to edit the create method? – a3uge Apr 06 '11 at 13:38
  • I take it I have to do something like... @topic = section.current_user.topics.build(params[:topic])... but obviously doesn't work because current_user isn't a property of section. – a3uge Apr 06 '11 at 13:48
  • current_user is a Devise helper. It is nil if no user is logged in and a user object, if a user is logged in. In your before filter you need something like this: before_filter :authenticate_user!, :except => [:index]. This would require signing in for all methods of this controller except index. Take a look at my link (and the other chapters of the tutorial). – Markus Proske Apr 06 '11 at 15:04
  • I already have basic authentication. I'm having trouble with the create method and how to structure that. In my topics controller in my create method, I have something like @topic = current_user.topics.new(params[:topic]) but then the topic doesn't know what section it is. I need the user, topic, section, and the topic content all in the database. – a3uge Apr 06 '11 at 15:29
  • This depends on your settings in the models. If you have topic belongs_to user and user has_many topics then you can access current_user.topics. Remember, current_user is just an user object. What you will need is the build method to build relations and then tie them together and save them to the database. Another example for an update method where user has articles, articles has comments and comments are tied to users: `@article = Article.find(params[:article_id]) @comment = @article.comments.build(params[:comment]) @comment.user = current_user @comment.save` – Markus Proske Apr 06 '11 at 16:23
  • 1
    @MarkusProske the link is broken. – HM1 Jun 27 '13 at 01:17