Destroying Nested Comments - ruby-on-rails

Good Morning,
I'm having an issues with nested comments. I have a partial which shows these but I want to add a delete snippet at the bottom of .each one.
Here is the partial:
_snippets.html.erb
<% #snippets.each do |snippet| %>
<%= raw(snippet.content) %>
<% if can? :manage, snippet %>
<%= link_to 'delete', book_snippet_path(snippet), :method => :delete %>
<% end %>
<% end %>
Here are my routes:
book_snippets POST /books/:book_id/snippets(.:format) snippets#create
edit_book_snippet GET /books/:book_id/snippets/:id/edit(.:format) snippets#edit
book_snippet PATCH /books/:book_id/snippets/:id(.:format) snippets#update
PUT /books/:book_id/snippets/:id(.:format) snippets#update
DELETE /books/:book_id/snippets/:id(.:format) snippets#destroy
Here is the stack error, showing no route matches update?
No route matches {:action=>"update", :controller=>"snippets", :id=>nil, :book_id=>#<Snippet id: 4, content: "<p>YACHT!</p>\r\n", book_id: 4, created_at: "2013-11-15 09:12:20", updated_at: "2013-11-15 09:12:25", approved: true, user_id: 1>, :format=>nil} missing required keys: [:id]
I know it's probably something stupid I'm missing but would really like some help figuring this one out.
Thanks :)

You are missing book_id . You routes says
DELETE /books/:book_id/snippets/:id(.:format)
needs a book_id in path. So need to pass #book object as well in the arguments.
<%= raw(snippet.content) %>
<% if can? :manage, snippet %>
<%= link_to 'delete', book_snippet_path(#book, snippet), :method => :delete %>
<% end %>

Related

ActionController::UrlGenerationError - missing required keys

I am new to rails and am trying to build my first MVC app. I am trying to create a link file path and get this error message -
ActionController::UrlGenerationError in Pages#my_profile
No route matches {:action=>"show", :car_id=>10, :controller=>"bookings"}, missing required keys: [:id]
This is the code I am using in the view
<% current_user.bookings.each do |booking| %>
<%= link_to booking.car.make, car_booking_path(booking[:id])%></h2>
<% end %>
When I type booking into the rails console I have access to the following hash
#<Booking id: 10, start_date: "2020-08-18", end_date: "2020-08-19", status: nil, user_id: 5, car_id: 5, created_at: "2020-08-18 17:34:41", updated_at: "2020-08-18 17:34:41">
so am unsure as to why, when booking[:id] is passed it is not picked.
my route is
car_booking GET /cars/:car_id/bookings/:id(.:format) bookings#show
Does anyone have any idea on what I am missing?
any help would be massively appreciated.
Try:
<% current_user.bookings.each do |booking| %>
<%= link_to booking.car.make, [booking.car, booking] %></h2>
<% end %>
See, you have a nested route:
car_booking GET /cars/:car_id/bookings/:id(.:format) bookings#show
Which expects both car_id and id. You're only passing in one value, booking[:id], which is in the first position, so it is interpreted as car_id (although it's actually booking.id). There is no second value in your arguments, so you get the missing required keys: [:id] message.
Note that if you used shallow nesting, something like this:
Rails.application.routes.draw do
...
resources :cars do
resources :bookings, shallow: true
end
...
end
then you would just do:
<% current_user.bookings.each do |booking| %>
<%= link_to booking.car.make, booking_path(booking)%></h2>
<% end %>
Also note that you can typically do booking_path(booking) instead of booking_path(booking.id). In fact, as stated in the docs, you can use the pithier:
<% current_user.bookings.each do |booking| %>
<%= link_to booking.car.make, booking %></h2>
<% end %>
If you don't want to use shallow nesting, you can do:
<% current_user.bookings.each do |booking| %>
<%= link_to booking.car.make, [booking.car, booking] %></h2>
<% end %>
...and, as discussed in the docs Rails will infer the car_booking_path helper.
In your question, you say you have access to the following hash:
#<Booking id: 10, start_date: "2020-08-18", end_date: "2020-08-19", status: nil, user_id: 5, car_id: 5, created_at: "2020-08-18 17:34:41", updated_at: "2020-08-18 17:34:41">
FYI, that's not a hash. That's an instance of the Booking class which inherits from ActiveRecord::Base. To get the id from that instance, do booking.id, not booking[:id].
As per the output from the routes, you need to pass two arguments id and car_id.
Try the below:
<%= link_to booking.car.make, car_booking_path(car_id: booking.car_id, id: booking.id)%></h2>

Rails, link_to method: :delete breaks after child element (comment) instantiated

I'm on a video show page (which belongs to a post). The link_to delete works just fine until I create a comment on that video show page. I have a series of capybara tests that validate that the link_to delete video is working until I create a comment on that video at which point rails returns...
Failure/Error: <%= link_to "Delete Video", post_video_path(#video), method: :delete %>
ActionView::Template::Error:
No route matches
Not sure what's going on here or how to fix it. I stuck a pry in and the first two tests that hit it I checked the path...
post_video_path(#video)
which returned a valid path, e.g.
[1] pry(#<#<Class:0x007f891941dee0>>)> post_video_path(#video)
=> "/posts/1/videos/1"
When the spec instantiates a comment, the path reads as follows...
[1] pry(#<#<Class:0x007f891c2fd0a8>>)> post_video_path(#video)
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"videos", :post_id=>#<Video id: 1, user_id: 1, post_id: 1, title: "18title", url: "https://www.youtube.com/watch?v=tYm_182oCVdSM", embed_id: "https://www.youtube.com/watch?v=tYm_182oCVdSM.spli...", tags: nil, created_at: "2016-10-16 22:12:30", updated_at: "2016-10-16 22:12:30">, :video_id=>"1"} missing required keys: [:id]
videos_controller.rb
def show
#video = Video.find(params[:id])
#user = #video.user
#post = #video.post
#comment = Comment.new
#comments = #video.comments
end
videos/show.html.erb
<%= #video.title %>
<%= content_tag(:iframe, nil, src: "//www.youtube.com/embed/#{#video.embed_id}") %>
<% binding.pry %>
<%= link_to "Delete Video", post_video_path(#video), method: :delete %>
<%= link_to('Back', user_post_path(#user, #post)) %>
<h3>Comments</h3>
<%= form_for [#video, #comment] do |f| %>
<%= f.label(:body, "Comment") %>
<%= f.text_area(:body) %>
<%= f.submit("Submit Comment") %>
<% end %>
<% #comments.each do |comment| %>
<%= comment.body %>
<%= comment.user %>
<% end %>
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users, only: [] do
collection do
get '/show_profile', to: 'users#show_profile', as: 'my_profile'
get '/show_log', to: 'users#show_log', as: 'my_log'
end
resources :posts, only: [:new, :create, :show]
end
resources :posts do
resources :videos
end
resources :videos do
resources :comments
end
root 'home#index'
end
models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :video
validates :body, presence: true
end
Please let me know if you would like to see any particular file or code.
Thanks!
Generally speaking - when you use a path name that has the names of two models, you need to pass it two models.
eg in your case, your path is post_video_path(#video) - what this expects is for you to pass it a post and a video eg post_video_path(#post, #video)
if you don't... then it will get confused, possibly in a way you didn't expect. In this case, I'm guessing that it's taking the id of the video, and assuming it's the post_id.
You can tell it's confused by look at this error message:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"videos", :post_id=>#<Video id: 1, user_id: 1, post_id: 1, title: "18title",
Specifically the part that has: :post_id=>#<Video id: 1, ... -> it's putting the video in the post_id. Quite possibly it only "worked" before because you had a single post, and a single video... and thus when it used the id of 1 from the video as the post-id... the video was already assigned to the post (that also had an id of 1)... but once you delete that one, it no longer exists. This is a total guess - it doesn't matter if this is how Rails got confused, as long as you recognise where the error is coming in.

Rails: Fail to pass multiple variable-ids to nested route

In my project are 2 nested resources:
Rails.application.routes.draw do
resources :posts do
resources :comments
end
root 'posts#index'
end
I'm rendering a collection of comments with the use of a partial _comment.html.erb
<%= render partial: "comments/comment", collection: #post.comments %>
The partial looks like this
<div class="comment_wrapper">
<p class="comment_name"><%= comment.name %></p>
<p class="comment_date"><%= comment.created_at %></p>
<p class="comment_body"><%= comment.body %></p>
<%= link_to "Delete comment", post_comment_path(#post.id, id: comment.id), method: :delete%>
</div>
The problem is with that nested route in the "Delete comment" link.
I keep failing to pass in the :id key. I've tried a couple of different ways to pass the variables in the link, but keep getting the same error, that the :id key is missing. When I replace the link with a paragraph to display comment.id, it gets displayed perfectly, so it's definately available in my view.
No route matches {:action=>"show", :controller=>"comments", :format=>nil, :id=>nil, :post_id=>11} missing required keys: [:id]
As you can see it also tries to call the "show" action, but I bet that will be solved as soon as it passes the ids properly.
Any ideas what I could be doing wrong here?
As you can see the error is
No route matches {:action=>"show", :controller=>"comments", :format=>nil, :id=>nil, :post_id=>11}
And in your link_to has comment.id in it:
<%= link_to "Delete comment", post_comment_path(#post.id, id: comment.id), method: :delete %>
It means that you are passing an object with no id in it (not saved in database). You are probably building your comments and that is the reason they do not have ids yet.
One of the solutions to this problem is to use your link_to like this:
<%= link_to("Delete comment", post_comment_path(#post, comment), method: :delete) unless comment.new_record? %>
Which will not show the link for new records, because you can't delete what does not exist in database yet.

No route matches [POST] - Rails destroy

I am new to RoR and still don't have enough experience on solving the different errors that may appear to me. In this case I am designing a blog where I can post articles. More specifically, my problem is related to deleting these articles.
As far as I know, writing:
resources :articles
in the routes file is an alternative for writing:
get "/articles" #index
post "/articles" #create
delete "/articles/:id" #delete
get "/articles/:id" #show
get "/articles/new" #new
get "/articles/:id/edit" #edit
patch "/articles/:id" #update
put "/articles/:id" #update
When I try to delete an article I get the following error:
No route matches [POST] "/articles/1"
The code I wrote was:
View
<% #articles.each do |art| %>
<%= art.title %>
<div>
<%= art.body %> - <%= link_to "Delete", art, method: :delete %>
</div>
<% end %>
Controller
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
It sounds like you have this in your view:
<%= art.body %> - <%= link_to "Delete", art, method: :destroy %>
But you actually need:
<%= art.body %> - <%= link_to "Delete", art, method: :delete %>
I'd advise double-checking this in your app based on your reply to a comment from #GonzaloRobaina.
It looks to me like you're missing the correct path in your code. It should work with something like this :)
<%= link_to "Delete, article_path(art), method: :delete %>

Rails link_to issue

I'm new to rails and have been working on creating a basic survey app to work through nested resources.
Here's what my eventual data structure should look like:
survey
question, with a foreign of survey
answer, with a foreign of question
choice, with a foreign of the user who is taking the survey and answer id which he will select
I was able to create the survey and question structure. But I'm running into some trouble with the answers. It's throwing an error on the last line in my question's show.html.erb file where I'm trying to link_to my new answer.
Here's the question's show.html.erb file:
<div id='question'>
<h2><%= #question.title %></h2>
<% if #question.single_response %>
<p>Single response</p>
<% else %>
<p>Multiple response</p>
<% end %>
</div>
<%= link_to "Edit Question", [:edit, #survey, #question] %>
<%= link_to "Delete Question", [#survey, #question], method: :delete, data: { confirm: "Are you sure you want to delete this question?"} %>
<p>Answers</p>
<ul id='answers'>
<% #question.answers.each do |answer| %>
<li><%= link_to answer.title, [#survey, #question, answer] %></li>
<% end %>
</ul>
<p><%= link_to "Add Answer", new_survey_question_answer_path([#survey,#question]) %></p>
Here's my routes.rb:
SurveyMe::Application.routes.draw do
resources :surveys do
resources :questions do
resources :answers
end
end
devise_for :developers
devise_for :users
I'm pretty sure the issue is the [#survey, #question] piece of the line. Any ideas what I should be putting in there?
Here's the error:
Showing /Users/thomashammond89/Test Survey.me/app/views/questions/show.html.erb where line #18 raised:
No route matches {:action=>"new", :controller=>"answers", :survey_id=>[#<Survey id: 2, title: "Test1", created_at: "2014-02-21 17:35:36", updated_at: "2014-02-21 17:35:36">, #<Question id: 2, title: "Question Test1", single_response: true, survey_id: 2, created_at: "2014-02-21 18:59:57", updated_at: "2014-02-21 18:59:57">], :id=>"2", :question_id=>nil, :format=>nil} missing required keys: [:question_id]
Extracted source (around line #18):
15 <li><%= link_to answer.title, [#survey, #question, answer] %></li>
16 <% end %>
17 </ul>
18 <p><%= link_to "Add Answer", new_survey_question_answer_path([#survey,#question]) %></p>
That should be:
new_survey_question_answer_path(#survey, #question)

Resources