CRUD operation for nested model in rails 3 - ruby-on-rails

I am new in rails 3, and following the guide in ruby site I build the first blog application.
However in the app,the model "Comment" do not have edit/update/delete operation.
Then I tried to add it,but I fails.
Instead of just generate model for model "Comment",I create the scaffold for model "Comment" using:
rails generate scaffold Comment commenter:string body:text post:references
And in the post.show page,I modify it like this:
<% #post.comments.each do |comment| %>
<tr>
<td><%= comment.commenter %></td>
<td><%= comment.body %></td>
<td><%= link_to 'Edit', edit_comment_path(comment) %></td>
<td><%= link_to 'Destroy', comment, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
They are listed,but when I click the 'edit' or 'delete' link,it will try to jump to:
http://localhost:3000/comments/1
And Then I will get the error:
No route matches [GET] "/comments/3/edit" or
No route matches [DELETE] "/comments/3"
I have no idea now.
Is there any demo out of box I can learn?
UPdate:
In the routes.rb:
resources :posts do
resources :comments
end
Note:the following is confided manually by myself.
config generated by rails is :
resources :posts
resources :comments
Why I modify it is that in the comment build form,the post url should be "/posts/1/comments" for create new Comment,otherwise the post url will be "/comments" which will not associate the post and the comment.

Did you configure your routes? Your config/routes.rb should contain
resources :comments
you can also run rake routes to see what are the available url for your application based on your resource configuration.
Edit:
For a demo you can try this video on youtube. However, you can find lots of videos in web regarding this.
Edit:
So seems you need your comment resource in two ways. Both as a nested resource of posts and top level resource as well. So you can have two things together then
resources :posts do
resources :comments
end
resources :comments

Since you've nested resources, you should use:
edit_post_comment_path(#post, comment)
to be even clearer:
<td><%= link_to 'Edit', edit_post_comment_path(#post, comment) %></td>
<td><%= link_to 'Destroy', post_comment_path(#post, comment), confirm: 'Are you sure?', method: :delete %></td>

Related

No route matches [POST] - Adding route does not work

My method does not work.
I have a games library, where I can add, show, edit, and destroy. I want to expand it and add one more method clone to it.
Library created with rails g scaffold:
The clone method in games_controller.rb
def clone
#game.clone
respond_to do |format|
format.html { redirect_to games_url, notice: 'Game was successfully cloned.'}
format.json { head :no_content }
end
end
The call code for Clone in index
<% #games.each do |game| %>
<tr>
<td><%= game.title %></td>
<td><%= game.description %></td>
<td><%= link_to 'Show', game %></td>
<td><%= link_to 'Edit', edit_game_path(game) %></td>
<td><%= link_to 'Destroy', game, method: :delete, data: { confirm: '.. sure?' } %></td>
<td><%= link_to 'Clone', game, method: :clone, data: { confirm: '.. sure?' } %></td>
</tr>
<% end %>
The routes code in routes.rb
resources :games do
resources :comments
post 'clone'
end
a view in games library
You are doing it wrong. You have method: :clone which is not valid. The valid values for method option for link_to are post, patch, put and delete.
method: symbol of HTTP verb - This modifier will dynamically create an
HTML form and immediately submit the form for processing using the
HTTP verb specified. Useful for having links perform a POST operation
in dangerous actions like deleting a record (which search bots can
follow while spidering your site). Supported verbs are :post, :delete,
:patch, and :put. Note that if the user has JavaScript disabled, the
request will fall back to using GET. If href: '#' is used and the user
has JavaScript disabled clicking the link will have no effect. If you
are relying on the POST behavior, you should check for it in your
controller's action by using the request object's methods for post?,
delete?, patch?, or put?.
Now coming to your routes, when you do rake routes, you will see the below
game_clone POST /games/:game_id/clone(.:format) games#clone
So, the link_to should look like below
<%= link_to 'Clone', game_clone_path(game), method: :post, data: { confirm: '.. sure?' } %>
Couldn't find Game without an ID
Ok, you are cloning a Game instance. Normally you look for an instance with an :id, but with your current routes, the :game_id will passed in the params which is not appropriate to want you need. You should change your routes to pass :id instead of :game_id. So the final solution will be
Final Solution:
resources :games do
resources :comments
post 'clone', on: :member
end
The above will create a path helper with the below
clone_game POST /games/:id/clone(.:format) games#clone
Now change the link_to with the new path helper and you are good to go
<%= link_to 'Clone', clone_game_path(game), method: :post, data: { confirm: '.. sure?' } %>
Note:
You should be careful when adding custom routes to your resourceful routes. This will create path helpers with unnecessary keys such as :*_id(:game_id in your case). These routes should be added as collection route or a member route depending upon the scenario. For more info refer these guides

Undefined method ` _path' on Show action of nested resources

I'm a rails rookie.
I did some routing changes on my first rails app, in this app you can create Congresses and each of those has_many categories, each category belongs_to (only one) Congress, so, my routes looks like this:
resources :congresses do
resources :categories do
resources :presentations
end
resources :news
end
I changed some things on views for Category, so, link_to now is in the form congress_category_path, those links works like a charm. After that, I add [#congress, #category] on the form_for category, so, the app lets you create a category. Here is where my problem starts...
at this part of view:
<tbody>
<% Congress.find(params[:congress_id]).categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<td><%= category.description %></td>
<td><%= category.presentations %></td>
<td><%= link_to 'Show', category %></td>
<td><%= link_to 'Edit', edit_congress_category_path(category) %></td>
<td><%= link_to 'Destroy', category, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
each category is an instance, <%= link_to 'Show', category %> extracts category_path and not congress_category_path... where can I change that specific route ?
this is giving me an
undefined method category_path for #<#<Class:0x9961e00>:0x929a360>
I even tried something like
congress_category_path ([#congress, category])
but this didnt work either
I really appreciate your help, thanks!!
It seems like you've got the syntax wrong.
From here: http://guides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects, your options for constructing a path out of nested resources are either:
congress_category_path(#congress, category)
or
(note the _path method does not accept an array parameter)
url_for([#congress, category])
(whereas the url_for method does).
Let me know if that helps!
several remarks
1. limit resource depth
resources :congresses do
resources :categories do
resources :presentations
end
end
The guidelines do not recommend having too nested routes. Instead you might want to take a look at shallow routes
2 How path helpers are constructed
Next you need to understand that
resources :congresses do
resources :categories
end
Generates CRUD routes of the following format (example for a #show)
GET /congresses/:congress_id/categories/:id => congresses/categories_controller#show
You can see that this "route" has two parameters congress_id and id so the path helpers that Rails generates can take two positional arguments congress_id and id and the path helpers are expected to be written as such
congress_category_path(#congress, category)
Note : it is somewhat the equivalent of
congress_category_path(congress_id: #congress.id.to_s, id: category.id.to_s)
3 Using shallow routes you can use the simple route
# config/routes.rb
resources :congresses do
resources :categories, shallow: true
end
# views/your_view.html.erb
<%= link_to 'Show', category %>

How to delete association with parent controller update action? Rails

I'm using Rails 4
I need to delete association Box with link_to method. The problem is that I have to do it from parrent controller and method: patch. my corrent code is doing nothing because I don't know how to use data: for link_to.
#views/modifications/show.html.erb
<% #modification.boxes.each do |box| %>
<tr>
<td><%= box.name %></td>
<td><%= link_to "delete", #modification, remote: true, method: :patch %></td>
</tr>
<% end %>
By the way, this is used with Ajax so page doesn't need to be reloaded.
I have to do it
You don't have to do anything in any way - if Microsoft can release Windows for all the PC's in the world, I'm sure you can get this working.
You have several issues, the most important of which being... how do you identify the box object to delete?
The whole point of nested resources (which is what you need) is to give you the ability to identify a "parent" object and a child object.
Your current setup prevents you from identifying the box you wish to remove. Ideally, you should use the following code to get it sorted:
#config/routes.rb
resources :modifications do
resources :boxes, only: :destroy
end
#app/views/modifications/show.html.erb
<% #modification.boxes.each do |box| %>
<tr>
<td><%= box.name %></td>
<td><%= link_to "delete", [#modification, box], remote: true, method: :delete %></td>
</tr>
<% end %>
#app/controllers/boxes_controller.rb
class BoxesController < ApplicationController
def destroy
#modification = Modification.find params[:modification_id]
#box = #modification.boxes.find params[:id]
#box.destroy
end
end
Try to using link_to with delete method on box destroy path, like this:
<%= link_to 'Delete', box_path(box), method: :delete, remote: true %>

Issue in rails 4.0 with creating a link_to for a delete action

This is my first project in rails, which is to create a table that will store data about games. I'm able to display data from the table about winner score, loser score, etc. However, I have issues with my table column that contains delete links for each game.
Here's my code in the games controller for the delete method:
def delete
#game = Game.find(params[:game])
#game.destroy()
redirect_to :action => 'index'
end
A snippet of my table code, which includes the line for the link_to command
<% #games_items.each do |t| %>
<tr>
<td><%= t.winner.name %></td>
<td><%= t.loser.name %></td>
<td><%= t.challenger.name %></td>
<td><%= t.winner_score %></td>
<td><%= t.loser_score %></td>
<td><%= link_to 'Delete', delete_game_path(id: t.id)%></td>
</tr>
<% end %>
In the routes file I called
resources :games
Which, to my knowledge, helps generate the base routing. Could anyone help me figure out why my link_to is not working?
If you use (which is adviced) resources:
a) Your action for deleting records should be named destroy.
b) Game is searched for with :id parameter:
def destroy
#game = Game.find(params[:id])
#game.destroy
redirect_to :action => 'index'
end
c) Your link should be:
<%= link_to 'Delete', t, method: :delete %>
since the path is the same as for the show action, the only thig that changes is HTTP method.
The format for the delete call is:
<%= link_to 'Delete', game_path(t.id), :method => :delete %>
use rake routes to learn about the available routes, including generated route helpers, and the controller/action handling the request.
I had similar issue on rails 4.2.1, even with the :method => :delete on link_to it still routes to show method.
But using button_to method as below works!
<%= button_to "delete", article_path(:id => article.id), :method => :delete %>
button_to creates a form around the button and then posts to the delete method, by adding a hidden field named _method with value delete rails uses this to route to the destroy method in your controller.
Try to use <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> before <%= javascript_include_tag "application" %> in your layout, and also delete
//= require jquery
line in your application.js.
This was the case for me. No idea why it didn't worked with original rails jquery.js file.

Rails 3 - Nested Routes "NoMethodError" despite being listed in rake routes

Ok guys so I have a nested route like this:
resources :apps do
resources :forms
end
In my form index I have this block:
<% #forms.each do |form| %>
<tr>
<td><%= form.app_id %></td>
<td><%= form.title %></td>
<td><%= link_to 'Show', app_form(#app,form) %></td>
<td><%= link_to 'Destroy', form, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
The page throws a NoMethodError on the app_form line; however I think I am passing in the app and form in correctly (I've also tried to pass in the #app.id). Calling rake routes... the route is even displayed:
app_form GET /apps/:app_id/forms/:id(.:format) {:controller=>"forms", :action=>"show"}
Any help would be greatly appreciated!
Try app_form_path(#app, form) instead (you need to append _path to the route name).
Not only nested routes,For each routes you using, You need to append _path or _url with route name.
So here juz try app_form_path(#app,form) or app_form_url(#app,form)

Resources