Asociation problems

Hi,

I'm trying to develop a simple blog aplication, with no scaffolding help. I create the model post and comment, and stablished the asociations:

class Post < ActiveRecord::Base has_many :comments validates_presence_of :title, :poster, :content end

class Comment < ActiveRecord::Base   belongs_to :post end

But, when I try to get the comments in a post I get error:

SQLite3::SQLException: no such column: comments.post_id: SELECT * FROM "comments" WHERE ("comments".post_id = 18)

Extracted source (around line #7):

4: <th>Commenter</th> 5: <th>Comment</th> 6: </tr> 7: <% for comment in @comments %> <tr> 8: <td><%=h comment.commenter %></td> 9: <td><%=h comment.comment %></td>

No such column? Error in @comments, here is the controller:

def showcomments @post = Post.find(params[:id]) @comments = @post.comments end

I don't know where the problem is :S

Thanks for your answers

Does the table comments have a column post_id? A belongs_to and has_many relationship is by default always linked in the child object with the parent's id!

I thought the relation belongs_to automatically creates this column.

This is getting me crazy:

Error:

You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.

/home/diego/blog/app/controllers/myblog_controller.rb:68:in `createcomment'

Action Controller:

def createcomment @post = Post.find(params[:id]) @comment = @post.comments.build @comment.comment = params[:comment][:comment] @comment.commenter = params[:comment][:commenter] redirect_to :url => {:action => 'showpost', :id => @post.id} end

So the problem is in params, it is nil.. Form:

<h1>New Comment</h1>

<% form_for :comment, @comment, :url => {:action => 'createcomment', :id => @post.id} do |f| %> <p> <%= f.label :commenter%> <br> <%= f.text_field :commenter%> </p> <p> <%= f.label :comment%> <br> <%= f.text_area :comment%> </p> <p> <%= f.submit "Comentar"%> </p> <% end %>

A relationship tells Rails to _expect_ the relevant id column, not to create it. The only way that the db structure will change is if you provide a migration (unless you change it manually of course).

Colin

I see.. I did the migration then, thank you (thanks to rails for the migrations these problems with db are quickly fixed ^^).

But I have the problem with the form for comments:

Error:

You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.

/home/diego/blog/app/controllers/myblog_controller.rb:68:in `createcomment'

Action Controller:

def createcomment @post = Post.find(params[:id]) @comment = @post.comments.build @comment.comment = params[:comment][:comment] @comment.commenter = params[:comment][:commenter] redirect_to :url => {:action => 'showpost', :id => @post.id} end

So the problem is in params, it is nil.. Form:

<h1>New Comment</h1>

<% form_for :comment, @comment, :url => {:action => 'createcomment', :id => @post.id} do |f| %> <p> <%= f.label :commenter%> <br> <%= f.text_field :commenter%> </p> <p> <%= f.label :comment%> <br> <%= f.text_area :comment%> </p> <p> <%= f.submit "Comentar"%> </p> <% end %>

I see.. I did the migration then, thank you (thanks to rails for the migrations these problems with db are quickly fixed ^^).

But I have the problem with the form for comments:

Error:

You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.

/home/diego/blog/app/controllers/myblog_controller.rb:68:in `createcomment'

Action Controller:

def createcomment @post = Post.find(params[:id]) @comment = @post.comments.build @comment.comment = params[:comment][:comment] @comment.commenter = params[:comment][:commenter]

Perhaps params[:comment] is nil? Have a look in the log to see what parameters have been posted with the form. In this situation if I still cannot see the problem I would use ruby-debug to break in and look at the variables.

redirect_to :url => {:action => 'showpost', :id => @post.id} end

So the problem is in params, it is nil.. Form:

<h1>New Comment</h1>

<% form_for :comment, @comment, :url => {:action => 'createcomment', :id => @post.id} do |f| %>

Are you sure the syntax here is correct? Are you sure you need :comment and @comment in form_for?

Hi     This be approached in railsway You have post has_many comments and comment belong to post ?

So can create two controllers Posts controller and Comments controller And in app/controllers/posts_controller.rb add

def show    @post = Post.find(params[:id])    @comment = @post.comments.new end

Now the view app/views/posts/show.html.erb

<% form_for [@post, @comment] do |f| %>    <p> <%= f.label :commenter%> <br> <%= f.text_field :commenter%> </p> <p> <%= f.label :comment%> <br> <%= f.text_area :comment%> </p> <p> <%= f.submit "Comentar"%> </p>

<% end %>

Then in app/controllers/comments_controller.rb

def create            @post = Post.find(params[:post_id])            @post.comments.new(params[:comment]).save            redirect_to(post_path(@post)) end

         edit routes.rb map.resources :posts, :has_many => [:comments]

     Thts all And one more you can move this two controllers to a namespace Blog This can be done by ./script/generate controller Blog::Posts ./script/generate controller Blog::Comments

    So the changes at three places above They are

<% form_for [:blog,@post, @comment] do |f| %>

            and

redirect_to(blog_post_path(@post))

        and

map.namespace(:blog) do |b|        b.resources :posts, :has_many => [:comments] end

Sijo