Problem with @story = Story.find(params[:story_id]) in rails 3
I have an app that I have recently upgraded to rails 3
In my comments controller I have
def creat开发者_C百科e
@cuser = @current_user
@story = Story.find(params[:story_id])
@story.comments.create(:user_id => @cuser.login,:body => params[:comment][:body])
respond_to do |format|
format.html { story_path}
format.js
end
end
In story.rb
I have has_many :comments
In comment.rb
I have belongs_to :story
When I try to create a comment I get a
Couldn't find Story without an ID
This used to work. Any ideas why it doesn't any more ? What else could be affecting it? Could it be a routing issue?
Your form definition should look like this:
<%= form_for [@story, Comment.new] do |form| %>
<div id="body">
<%= form.text_field :body %>
</div> <% form.hidden_field :user_id, :value => @current_user.login %>
<p>
<%= submit_tag 'Comment' %>
</p>
<% end %>
Your form uses POST /comments
instead of POST /stories/:story_id/comments
action.
It should have thrown an exception about a missing POST /comments
route, that's why I wasn't sure about my solution. But your routes have the comments
resources for some reason. So it knows how to create the URL, but it doesn't know it should include the /stories/:story_id
part.
Another thing here is you pass current_user with the form. It's bad since anyone who knows how to use firebug or any other web-master tools can change this field to, say, your login and post comments as if it were you. You should assign the user field in your create action of the controller.
And one more. I really can't see why you would need all this routes. If it was my app, routes would look something like this:
Telling_tales::Application.routes.draw do
resource :session
resource :stories #really can't see why you need a singular route here
resource :user
resources :users do
get 'register' => 'create', :on => :collection #maps to 'users#create'
end
resources :stories do
resources :comments
collection do
get ':login' => 'show' #it seems illogical to place this route under `stories` namespace
#if you wanted to display stories of one particular user, you'd better make it `/users/:user_id/stories`
get 'search'
end
root :to => 'stories#index'
end
Take a look at this and this guides.
I assume you have the following route-configuration:
resources :stories do
resources :comments
end
If that's the case, you have to use params[:story_id]
.
@story = Story.find(params[:story_id])
yes, it can be a routing issue. You have probably spotted that the routing dsl has changed, and I guess you are messing around with it. Looks like you used to have a route something like
`map.resources :stories
and you have (maybe) replaced that with something like
resources :stories do
resources :comments do
collection do
post :create
end
end
end
I'm only guessing , but I think this would give the sort of error you are seeing - you need a route like
resources :stories do
resources :comments
end
which will automatically generate the create route, or if you want to specify it more precisely
resources :stories do
resources :comments do
member do
post :create
end
end
end
精彩评论