The following problem has been fixed, I added an 's' to the end of comments, when it should just be comment, but a new problem has arisen at the bottom of this post.
I am trying to get threaded comments for my already existing comments system by following the answer to this man's question: Reddit-style nested/threaded/indented comments for Rails?
When I try to access my article show page, I get the following error: undefined method `children' for #
Here's the view from my article show page that is problematic:
<div id="comment <%= comment.id %>">
<%= comment.title %>
| <%= link_to "Edit Comment", edit_article_comment_path(#commentable, comment) %>
| <%= link_to 'Delete Comment', [#commentable, comment], :confirm => "Are you sure?", :method => :delete %><br />
<%= comment.content %><br />
**<%= render :partial => 'comments/comment', :collection => #comments.children %>**
<%= comment.user.name %><br /><br />
</div>
It's the render portion that is having a problem.
If I take out the children part from the comments, I get this in my console:
The recursion never stops. I get this: Rendered comments/_form.html.erb (14.9ms) Rendered comments/_comment.html.erb (2.0ms) Rendered comments/_comment.html.erb (7.3ms) Rendered comments/_comment.html.erb (12.3ms) Rendered comments/_comment.html.erb (17.9ms) Rendered comments/_comment.html.erb (22.3ms) Rendered comments/_comment.html.erb (26.8ms) Rendered comments/_comment.html.erb (31.6ms) Rendered comments/_comment.html.erb (36.2ms) ....
I do not know why it keeps rendering.
None of the comments have children, so it should stop.
Here's the 'show' part of the article controller:
def show
#article = Article.find(params[:id])
#commentable = Article.find(params[:id])
#comments = #commentable.comments.paginate(:page => params[:page])
#comment = Comment.new
#title = #article.title
end
My only explanation is that maybe there aren't any children comments, so will_paginate does not know what to do with it, so it throws an error at me.
New Problem, I am having problem with routing for comments. I am using polymorphic associations for my comments so they can be used for different models(articles, profiles, pictures, etc.), but I do not know how to create the routing paths in my view.
Here is what I have now:
<div id="comment <%= comment.id %>">
<%= comment.title %>
| <%= link_to "Permalink", article_comment_path(#commentable, comment) %>
| <%= link_to "Reply", new_article_comment_path(#commentable, #comment_child) %>
| <%= link_to "Edit Comment", edit_article_comment_path(#commentable, comment) %>
| <%= link_to 'Delete Comment', [#commentable, comment], :confirm => "Are you sure?", :method => :delete %><br />
<%= comment.content %><br />
<%= comment.user.name %><br /><br />
<%= render :partial => 'comments/comment', :collection => #comment.children %>
</div>
There is an abundant number of pathing errors that won't work for other models. I am using: article_comment_path, new_article_comment_path, and edit_article_comment_path. By the way, this is inside of a for each loop, which loops over an array of comments. I want something like "commentable_comment_path" or "new_commentable_comment_path", so I can use it for my other models.
One more quick question, will this fix my "reply" link? I am not sure if I am doing that right. I want the reply link to create a comment within a comment.
Thank you so much.
parent_id as you suggest is an integer reference to an object. To get the children for an object a you would look up all objects that have a parent_id of a.id.
As for the problem with the rendering: #comments is an array of comment objects - you have essentially asked for a page of comments by using paginate. I guess you want to render the comments themselves in which case :collection => #comments will do the job. This just means to use the partial for each item in the collection. The partial will then take care of rendering the children of each comment as per the linked answer.
Related
def edit
#exercise = Exercise.find(params[:exercise_id])
#play = #exercise.plays.find(params[:id])
end
def update
#exercise = Exercise.find(params[:exercise_id])
#play = #exercise.plays.find(params[:id])
if #exercise.plays.update_attributes(play_params)
redirect_to #exercise_path
else
render action: :edit
end
end
partial view that is being rendered to show all created plays has
<p><%= play.name %></p>
<p><%= play.sets %></p>
<p><%= play.reps %></p>
<%= link_to "edit", edit_exercise_play_path( #exercise, play) %>
that is plays_controller :edit, :update method, Actually i have two classes, one is ExerciseController and other one is PlaysController, ExerciseController has_many plays, i am rendering two partials one to create play and other one to show that play on same page on the partial which is rendering the play after creation, but now i want to add edit feature with edit_exercise_play_path,
<%= link_to "Edit", edit_exercise_play_path(#play) %>
after this i am facing unmatched constraint error.Thanks
resources :exercises do
resources :plays
end
Show.html.erb from ExercisesController
<h2>Your Workout Details </h2>
<p><%= #exercise.workout %></p>
<p><%= #exercise.mode %></p>
<p><%= #exercise.date.strftime("on %A at %H:%M Dated as %d %B") %></p>
<p><%= #exercise.length %></p><br />
<h3> Games you Played </h3>
<%= render #exercise.plays %>
<h3>Add new Game </h3>
<%= render 'plays/form' %>
<%= link_to "Edit", edit_exercise_path %> | |
<%= link_to "Destroy", exercise_path(#exercise), :confirm => "Are you
sure?", :method => :delete %> | |
<%= link_to "Back", root_path %>
" Logs "
Started GET "/exercises/5" for 127.0.0.1 at 2018-09-25 18:12:21 +0500
Processing by ExercisesController#show as HTML
Parameters: {"id"=>"5"}
Exercise Load (0.0ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
Rendering exercises/show.html.erb
Play Load (0.0ms) SELECT "plays".* FROM "plays" WHERE "plays"."exercise_id" = ? [["exercise_id", 5]]
Rendered collection of plays/_play.html.erb [6 times] (14.0ms)
Rendered exercises/show.html.erb (39.7ms)
Completed 500 Internal Server Error in 136ms (ActiveRecord: 0.0ms)
As per your routes, the path helper edit_exercise_play_path also require value for :exercise_id key. But you haven't passing any. Changing the link_to to below should fix your problem
<%= link_to "Edit", edit_exercise_play_path(#exercise, #play) %>
Update:
As per our discussion over the chat, the link_to edit should look like below
<%= link_to "Edit", edit_exercise_play_path(#exercise, play) %>
as you are rendering a partial with <%= render #exercise.plays %> which creates a play variable.
undefined method `model_name' for nil:NilClass
For this, you should change <%= render 'form' %> to <%= render 'form' , exercise: #exercise, play: #play %> and in the _form.html.erb change the first line of the form to <%= simple_form_for ([exercise, play]) do |f| %>
undefined method `update_attributes' for
Play::ActiveRecord_Associations_CollectionProxy:0x0000000f69c710
The reason for this error is in your update method you have have #exercise.plays.update_attributes(play_params). This means you are calling update_attributes on collection. You should change
if #exercise.plays.update_attributes(play_params)
to
if #play.update_attributes(play_params)
I've got this working now quite accidentally, but I don't understand what causes it to break when I explicitly specify what partials are to be used for rendering the resource/s. Can anyone explain it?
The index template for my Posts controller contained the following line, which was giving me an error:
<%= render partial: 'posts', collection: #posts %>
The error (in my browser) said:
NoMethodError in Posts#index
Showing /Users/applebum/Sites/rails_projects/eventful2/app/views/posts/_posts.html.erb where line #1 raised:
undefined method `any?' for #<Post:0x000001064b21f0>
Extracted source (around line #1):
1: <% if posts.any? %>
2: <div id="posts">
3: <% posts.each do |post| %>
4: <%= render partial: "posts/post", locals: { post: post } %>
Changing the problem line to
<%= render #posts %>
made the error disappear and the posts appear (displayed nicely in markup from the appropriate partials) as I had wanted and expected them to.
Here's my _posts.html.erb partial:
<% if posts.any? %>
<div id="posts">
<% posts.each do |post| %>
<%= render partial: "posts/post", locals: { post: post } %>
<% # render :partial => "comments/comments", :collection => post.comments %>
<% end %>
</div>
<% end %>
And the _post.html.erb partial it's referring to, if that matters:
<div class="post" id="post_<%= "#{post.id}" %>">
<div class="post_inner">
<%= link_to avatar_for(post.user, size: "small"), post.user.profile %>
<div class="post_body">
<div class="user-tools">
<% if can? :destroy, post %>
<%= link_to '<i class="fi-x"></i>'.html_safe, post, :method => :delete, remote: true, :class => "delete", :confirm => "Are you sure you want to delete this post?", :title => post.content %>
<% end %>
</div>
<h5 class="username">
<%= link_to post.user.name, post.user.profile %>
<span class="timestamp">• <%= time_ago_in_words(post.created_at) %> ago</span>
</h5>
<div class="content">
<%= post.content %>
</div>
<ul class="foot">
<li>Like<li>
<li>Share</li>
</ul>
</div>
</div>
</div>
And the relevant bits from the controller:
class PostsController < ApplicationController
respond_to :html, :js # Allow for AJAX requests as well as HTML ones.
before_filter :load_postable
load_and_authorize_resource
def index
#post = Post.new
#posts = #postable.posts
end
private #################
def load_postable
klass = [User, Event].detect { |c| params["#{c.name.underscore}_id"] } # Look for which one of these there's a ***_id parameter name for
#postable = klass.find(params["#{klass.name.underscore}_id"]) # Call find on that, passing in that parameter. eg Event.find(1)
end
Can anyone explain to me what's going on here? I couldn't find anything in the Layouts and Rendering guide at rubyonrails.org.
Thanks!
Your error comes from assuming :collection and #posts mean the same thing when rendering. From Rails Docs (point 3.4.5):
Partials are very useful in rendering collections. When you pass a collection to a partial via the :collection option, the partial will be inserted once for each member in the collection
So, if you use that, for each post, you will be doing post.any? which fails as any? isn't defined for a single post.
From the same docs, you should check if render returns Nil to see if the collection is empty:
<h1>Posts</h1>
<%= render(#posts) || "There are no posts." %>
PD: Use the partial to render only one post, not all of them.
GL & HF.
I am making a rails application. After a user has registered (I have
already created user registration with devise), they can fill out this
form that will contain their profile information. The form should
submit a post request to the create action in the informations controller, but for some reason I can't configure the routes properly. When i run rake routes, for informations#create, which is what the form should be going to, it has a blank path. There is also informations#index, which is what I guess its going to now. How do I get the form to go to informations#create if the path is blank? I have done this several times, and i can't find what is wrong. Here is the model:
class Information < ActiveRecord::Base
belongs_to :user
end
Here is the controller:
class InformationsController < ApplicationController
def new
#information = Information.new
end
def create
#information = Information.create(params[:information])
redirect_to student_path
end
def index
end
end
And here is the view for the new action.
<div class="span6 offset3 text-center">
<h1>Edit your information</h1>
<%= simple_form_for #information do |f| %>
<%= f.input :skills %>
<%= f.input :looking_for, :label => 'What help do you need?' %>
<%= f.input :my_idea %>
<%= submit_tag "Save", :class => "btn btn-primary btn-large" %>
<% end %>
</div>
Here is the line in the routes file:
resources :informations
I get the following error:
undefined method `information_index_path' for #<#:0x007f9c00c7b3e0>
Here is rake routes for the files
informations GET /informations(.:format) informations#index
POST /informations(.:format) informations#create
Here is my full stacktrace when trying to load the page that shows the form:
Started GET "/informations/new" for 127.0.0.1 at 2013-10-21 17:25:09 -0400
Processing by InformationsController#new as HTML
Rendered informations/new.html.erb within layouts/application (64.2ms)
Completed 500 Internal Server Error in 70ms
ActionView::Template::Error (undefined method `information_index_path' for #<#<Class:0x007ff03e8b34a0>:0x007ff03e8b23e8>):
2: <div class="span6 offset3 text-center">
3: <h1>Edit your information</h1>
4:
5: <% simple_form_for #information do |f| %>
6: <%= f.input :skills %>
7:
8:
app/views/informations/new.html.erb:5:in `_app_views_informations_new_html_erb__3172218935119285240_70334909089600'
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.7ms)
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (9.1ms)
Started GET "/informations/new" for 127.0.0.1 at 2013-10-21 17:25:09 -0400
Processing by InformationsController#new as HTML
Rendered informations/new.html.erb within layouts/application (8.3ms)
Completed 500 Internal Server Error in 13ms
ActionView::Template::Error (undefined method `information_index_path' for #<#<Class:0x007ff03e8b34a0>:0x007ff03e8708a8>):
2: <div class="span6 offset3 text-center">
3: <h1>Edit your information</h1>
4:
5: <% simple_form_for #information do |f| %>
6: <%= f.input :skills %>
7:
8:
app/views/informations/new.html.erb:5:in `_app_views_informations_new_html_erb__3172218935119285240_70334908978600'
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (2.0ms)
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.3ms)
Rendered /usr/local/rvm/gems/ruby-2.0.0-p247#firehose/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (14.0ms)
Your problem is related to the fact that the word information is both the plural and the singular form. Just like water, or paper, or evidence. Rails considers those words uncountable.
There are two things you can do: either name your model something else or edit the file config/initializers/inflections.rb like so:
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.uncountable %w( information )
end
Your form should be for one single information object. Not for a collection of information objects. Note that i have changed simple_form_for #informations to simple_form_for #information
<div class="span6 offset3 text-center">
<h1>Edit your information</h1>
<% simple_form_for #information do |f| %>
<%= f.input :skills %>
<%= f.input :looking_for, :label => 'What help do you need?' %>
<%= f.input :my_idea %>
<%= submit_tag "Save", :class => "btn btn-primary btn-large" %>
<% end %>
</div>
Also your failure is not because rails didn't generate information_index_path. Its because the named route for information#index is informations_path. the path is generated wrongly because you are using collection of objects.
Not sure if this will help, but try adding a = in front of simple_form_for. so that it will have a <%= instead of <%
I have a problem, trying to render partials in ruby on rails with the short notation for resoures. Somehow, RoR displays simply nothing that has to do with the partial, but i get no errors as well. I mean, the resulting HTML looks like the call for the partial simply wouldn't be there. I'm also confused, because i can see in the log, that rails rendered the partial 2 times (that would be ok, i have two test entries in the dev db), but i get no output in the browser. What am i doing wrong? Thanks in advance! This is my code:
app/views/tutorials/_tutorial.html.erb:
<div class="tutorial">
<h3><%= link_to tutorial.title, tutorial %></h3>
<span class="person"><%=h tutorial.tutor %></span>
<span class="time"><%=h german_time(tutorial.starts_at) %></span>
<span class="location"><%=h tutorial.location %></span>
<div class="description"><%=h tutorial.description %></div>
<% if admin? %>
<%= link_to 'Edit', edit_tutorial_path(tutorial) %> |
<%= link_to 'Delete', tutorial, :confirm => 'Are you sure?', :method => :delete %>
<% end %>
</div> <!-- end .tutorium -->
app/views/tutorials/index.html.erb:
<h2>Tutorials</h2>
<% render :partial => #tutorials %>
<% if admin? %>
<%= link_to 'New Tutorial', new_tutorial_path %>
<% end %>
console log:
Processing TutorialsController#index (for 127.0.0.1 at 2009-12-07 23:39:00) [GET]
Tutorial Load (0.6ms) SELECT * FROM "tutorials"
Rendering template within layouts/application
Rendering tutorials/index
Rendered tutorials/_tutorial (7.1ms)
Rendered tutorials/_tutorial (3.7ms)
Completed in 22ms (View: 17, DB: 1) | 200 OK [http://localhost/tutorials]
Try it with an equals:
<%= render :partial => #tutorials %>
I've set up a Rails form roughly following the instructions in this Railscast.
Here's the code for the form:
<% form_tag complete_todos_path, :method => :put do %>
<ul>
<div id="incomplete_todos">
<% #incomplete_todos.each do |todo| %>
<%= render :partial => todo %>
<% end %>
</div>
</ul>
<%= submit_tag "Mark as completed" %>
<% end %>
And here's the code for the todo partial:
<div class="todo">
<li>
<%= check_box_tag "todo_ids[]", todo.id %>
<%=h todo.name %>
<%= link_to 'edit', edit_todo_path(todo) %>
<%= link_to 'delete', todo, :confirm => 'Are you sure?', :method => :delete %>
</li>
</div>
It's working great, but I'm looking to start implementing AJAX and I need each checkbox to have a unique id. Right now, the input tags generated look something like this:
<input id="todo_ids_" name="todo_ids[]" type="checkbox" value="7" />
Every check box has the same id ("todo_ids_"), which is a problem. I suspect the solution is embarrassingly simple, but I'm not seeing it. Any tips?
<%= check_box_tag "todo_ids[]", todo.id, false, :id => "todo_id_#{todo.id}" -%> or whatever you want the id to be.
I consider this a bug with check_box_tag caused by the seemingly hackish nature of manually giving it the name todo_ids[] and the method code calling sanitize_to_id(name). I just ran into this yesterday and I'm contemplating a patch.
I ended up using a solution similar to Ryan's, but as I wrote in the comment I had to make a further change. In the form:
<%= check_box_tag "todo_ids[#{todo.id}]", todo.id %>
In the action called by the form:
Todo.update_all(["completed_at = ?", Time.now], :id => params[:todo_ids].keys)
Note the "params[:todo_ids].keys" at the end, which was a workaround to deal with the odd way the parameters were formatted:
"todo_ids" => {"5"=>"5"}
Can you try this and let us know if it works:
check_box_tag "todo_ids[#{todo.id}]", todo.id %>
This is the expected behaviour of check_box_tag, as this comment on a rejected fix explains.
You can use collection_check_boxes like this (haml syntax, sorry):
# Accumulate todos in a params hash like { todos: { to_complete: [] } }
= collection_check_boxes(:todos, :to_complete, #incomplete_todos, :id, :name) do |todo_builder|
= todo_builder.label do
# This is the result of calling :name on the todo, as specified
# calling the helper
= todo_builder.text
= todo_builder.check_box
Of course you can use partials inside the block, just pass and use the builder inside.
Check more options in the API docs.