Rails 4.1 link_to delete gives incorrect path - ruby-on-rails-4

For some reason I am unable to get the correct path for my destroy operation of a very simple model. Are my expectations incorrect?
My routes.rb includes:
resources :designs
And my view contains:
<% #designs.each do |design| %>
<%= link_to "Delete", design, :method => :delete %>
<% end %>
Which results in the HTML:
<a data-method="delete" href="/designs.49" rel="nofollow">Delete</a>
Which of course errors on
"No route for [DELETE] for /designs.49"
When I was expecting the rendered HTML to be:
<a data-method="delete" href="/designs/49" rel="nofollow">Delete</a>
Especially considering rake routes shows me:
DELETE /designs/:id(.:format) designs#destroy
My workaround is to replace: link_to "Delete", design... with: link_to "Delete", "/designs/#{design.id}"... (which works fine), but surely I am overlooking something basic, as no one should have to waste this much time to figure out the absolute most fundamental baseline case for a destroy operation.

Your code in the view could read like this using a _path helper:
<% #designs.each do |design| %>
<%= link_to "Delete", design_path(design), :method => :delete %>
<% end %>
But I guess I can see what you're trying to accomplish. To get the show action, you should be able to do this:
<% #designs.each do |design| %>
<%= link_to "Show", design %>
<% end %>
I wonder if this is a bug in Rails? What happens if you do this?
<% #designs.each do |design| %>
<%= link_to "Delete", url_for(design), :method => :delete %>
<% end %>

Try to replacing this in the helper tag.
<%= link_to "Delete", design_path, :method => :delete %>

Related

Will_paginate, Ruby on Rails, conditions

I am using will_paginate for my Rails project. Depending on 'Post' variable its 'mediatype' attribute I use either memo or photo and show results in different parts of the page. Will_paginate paginates both sides of the website together. If I have done 10 posts: 1 memo, 9 posts of photos, and 1 memo and I want to show 5 results per page, I will see on the front page one memo instead of two, and 4 photos. I use the same variable post and I have two different attributes how to make separate paginations for them? Here is my code. In fact I would like to add 'load more' button. It might a bit too complicated, so I will be satisfied with simple version of pagination. Still if you know how to make 'load more' buttons for two parts of the website, I will much appreciate. Thank you.
INDEX VIEW
<% content_for :memo_content do %>
<%= will_paginate #posts %>
<% #posts.reverse_each do |post| %>
<% if post.mediatype == "Memo" %>
<%= post.mediatype %>:
<%= post.title %>;
<% end %>
<% end %>
<% end %>
<% content_for :media_content do %>
<% #posts.reverse_each do |post| %>
<% if post.mediatype == "Photo" %>
<%= post.mediatype %>:
<%= post.title %>;
<% end %>
<% end %>
<% end %>
POSTS_CONTROLLER
def index
#posts = Post.order(name: :asc).paginate(page: params[:page], per_page: 5)
end
you can get count manually in controller and pass this count to will_paginate
Like:
#posts = Post.order(name: :asc).paginate(page: params[:page], per_page: 5)
from #posts get manually for both memo and posts of photos and pass this count in view.
<%= will_paginate #memo_count, :renderer => BootstrapPagination::Rails %>
<%= will_paginate #posts_of_photos_count, :renderer => BootstrapPagination::Rails %>

undefined method `model_name' for nested routes

I want to set up my models, such that my Posts has_many Comments and Comments has_many Replies. Comments are working fine. But my application starts breaking saying
undefined method `model_name' for "/posts/adas/comments/11/replies":String
when I try to setup the replies for comments. I cannot figure out what's triggering this error. I can add replies from my Rails console, and see them in the view, but adding the form_for tag breaks the code. Can anybody please point out what is the mistake and how I should be routing it?
Posts#show.html.erb
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<b><%= comment.username %></b>
<%= comment.name %>
<% if current_user.email == comment.username || current_user.admin? %>
<%= link_to 'Delete', [comment.post, comment],
:confirm => 'Are you sure?', :method => :delete %>
<% end %>
<p style = "text-indent: 3em">
<% comment.replies.each do |reply| %>
<i><%= reply.author %></i>
<%= reply.content %>
<% end %>
<%= form_for [#reply, post_comment_replies_path(#post, comment)] do |f| %>
<%= f.label :reply %>
<%= f.text_field :content %>
<%= f.submit("Reply") %>
<% end %>
<% end %>
</p>
</p>
<h3>Add a comment:</h3>
<%= form_for([#post, #post.comments.build]) do |f| %>
<%= f.label :comment %><br />
<%= f.text_area :name %>
<%= f.submit %>
<% end %>
replies_controller.rb
class RepliesController < ApplicationController
def create
#reply = #comment.replies.create(reply_params)
redirect_to post_path(#post)
end
private
def reply_params
params.require(:reply).permit(:content)
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
root 'welcome#index'
resources :posts do
resources :comments do
resources :replies
end
member do
put "like", to: "posts#upvote"
end
end
end
You're almost there, but you're not passing the parameters in the proper way to get the result that you want. At the moment you're passing in a url string where rails is expecting a resource object, hence the undefined method exception.
form_for(record, options = {}, &block)
The method takes a record and a hash of options that are optional.
The suspect line is
<%= form_for [#reply, post_comment_replies_path(#post, comment)] do |f| %>
The square brackets should only be used to define a resource and its associated resources which are then used to generate a url path. You should also explicitly state your url in the options hash unless it can be inferred from the resources you pass into form_for.
So it should look something like this, keeping with the way you are doing things.
<%= form_for #reply, url: post_comment_replies_path(#post, comment) do |f| %>
That's the case if you want to specify a url in form_for. However, why don't you just allow rails to generate the url for you?
<%= form_for [#post, comment, #reply] do |f| %>
This way rails should handle the routes.

Adding content block within Rails link_to tag

I have a link_to Rails tag in the following form:
<%= link_to 'Delete', somePath,
method: :delete, confirm: "Are you sure you want to delete this?",
class: "delete" %>
I've been trying to add a do block to add some arbitrary content block within the generated anchor tag. I've tried the following, but to no avail:
<%= link_to '<content>Delete' ... %>
# Which yields => <content>Delete in the DOM as a string instead of HTML
and
<%= link_to 'Delete' ... class: "delete" do %>
<content>
<% end %>
Which throws the error undefined method 'stringify_keys'. Any ideas?
try:
<%= link_to url_path ... class: "delete" do %>
Delete <content>
<% end %>

Ruby on rails Tutorial Missing partial articles/_form

Hi I have just started using Ruby on rails and have been following the tutorial # http://guides.rubyonrails.org/getting_started.html.
The problem I have got, is with 5.12 Using partials to clean up duplication in views.
I am getting the error ActionView::MissingTemplate in Articles#new.
It is looking for _form.html.erb , which is in the directory /app/views/articles/. So not sure why it cannot find it.
articles controller for new
def new
#article = Article.new
end
articles view for new
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
articles view for _form.html.erb
<%= form_for #article do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
< % end %>
Any help would be appreciated, need to know how to solve before going on to next part.
Hi I have got it to work by renaming _form.html.erb to_form as the error is looking for /apps/views/_form. I don't know if this is the correct way to solve the problem, as its says in the tutorial to name the file _form.html.erb.
would this cause issues in future doing it this way?
Check the file name, maybe you copied it wrong
I changed the file name to '_form.erb' and it worked. Still puzzled why the full suffix of 'html.erb' didn't work.

Rails 4.0 - wrong number of arguments (1 for 0) - for a nested 'IF' statement in a View

I am getting a ArgumentError in Members#index of wrong number of arguments (1 for 0) at the line <% if m.platforms %> in the following code. What extra argument do I have here? I don't know why I'm getting this error and searching on SO and Google hasn't given me an answer for this specific situation.
I have a rails 4.0 view that uses the following (simplified for readability):
View:
<% if #members %>
<% for m in #members %>
<% if m.platforms %>
<% for p in m.platforms %>
<%= link_to p.name, :controller => 'members', :action => 'platforms', :id => p.id %>
<% end %>
<% else %>
do something else...
<% end %>
<% end %>
<% else %>
...
Controller:
def index
if current_user
#members = current_user.members
end
end
You missed the "do" in your "for m in #members" and "for p in m.platforms"..
<% if #members %>
<% for m in #members do %> # add the "do"
<% if m.platforms %>
<% for p in m.platforms do %> # add the "do"
<%= link_to p.name, :controller => 'members', :action => 'platforms', :id => p.id %>
<% end %>
<% else %>
do something else...
<% end %>
<% end %>
<% else %>
do something else...
<% end %>
So terrible answer, but somehow it just kinda fixed itself. I hate when that happens... I would've rather know exactly what I did to get it working... I made a bunch of changes to the models that this view uses, so it was probably related to that.. Wish I could help the next person that comes across this. If you stumble across this and are having the same problem, please comment below and I will try to help, then update this answer with the correct one once we know what happened. Sorry google users...