RoR: partials with resources - ruby-on-rails

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 %>

Related

Ruby on Rails - why i am facing possible unmatched constraints[:exercise_id]

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)

Rendering a partial in rails. Specifying the partial for a resource gives an error, but not specifying a partial works fine. What gives?

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.

Hiding button in rails (Agile Web Development with Rails book)

This is my first question so I hope I can be as specific as possible, but don't be harsh.
I'm going through Agile Web Development with Rails and am very new to programming.
I want to hide a 'Checkout' button while I am on the order/new page so that it can't do anything nasty to the users purchase.
At the moment, I don't really understand how instance variables work, since it seems like no matter where I declare my instance variable, in a view or in orderscontroller#new, it always validates to true.
This seems to be the case because when I use the instance variable in the view to hide a div ( with hidden_div_if(condition == true) ) the buttons ALWAYS get hidden!
Not only that, but when I do:
<%= hidden_div_if( #hide_checkout_button == false ) do %>
<td><%= button_to 'Empty cart', cart, :method => :delete,
:confirm => 'Are you sure?' %></td>
<% end %>
<%= hidden_div_if( #hide_checkout_button == true ) do %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% end %>
BOTH buttons get hidden! How can that be!?!
In this example, I have placed the variable declaration in views\orders_form.html.erb:
<%= #hide_checkout_button = true %>
<%= form_for(#order) do |f| %>
<% if #order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#order.errors.count, "error") %>
prohibited this order from being saved:</h2>
<ul>
<% #order.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
...
Here is a discussion-forum with solutions for this problem, but they don't work for me and I don't know why: http://pragprog.com/wikis/wiki/Pt-G-2/version/35
And here is the question itself:
What happens if you click the Checkout button in the sidebar while the
checkout screen is already displayed? Can you find a way to disable
the button in this circumstance? (Hint: variables set in the controller
are available in layouts and partials as well as in the directly rendered
template.)
If you need any more information to help please ask, I'm not quite sure how much detail to provide or what information is important.
Thanks in advance :-)
def new
#cart = current_cart
if #cart.line_items.empty?
redirect_to store_url, :notice => "Your cart is empty"
return
end
puts 34
#hide_checkout_button = true
#order = Order.new
puts 37
respond_to do |format|
format.html # new.html.erb
format.json { render json: #order }
end
end
Started GET "/assets/logo.png" for 127.0.0.1 at 2012-11-13 20:33:40 +0000
Served asset /logo.png - 304 Not Modified (1ms)
[2012-11-13 20:33:40] WARN Could not determine content-length of response body.
Set content-length of the response or set Response#chunked = true
*
34
37
*
/orders/new
Started GET "/orders/new" for 127.0.0.1 at 2012-11-13 20:33:49 +0000
Processing by OrdersController#new as HTML
←[1m←[36mCart Load (1.0ms)←[0m ←[1mSELECT "carts".* FROM "carts" WHERE "carts
"."id" = ? LIMIT 1←[0m [["id", 63]]
←[1m←[35m (1.0ms)←[0m SELECT COUNT(*) FROM "line_items" WHERE "line_items"."c
art_id" = 63
The problem is a missing =. do <%= %> instead.
<%= hidden_div_if( #hide_checkout_button == true ) do %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% end %>
Also, for boolean checks you can just do if(boolean) which will evaluate the same as if you put == true/false
<%= hidden_div_if( #hide_checkout_button) do %>
#...
<% end %>
You want to set that variable on the method that calls the view. In this case it is the new method in OrdersController
def new
#hide_checkout_button = true
end
Edit:
add this to the hidden div just to see if it helps finding the element to set the attribute to
<%= hidden_div_if(#hide_checkout_button, id: 'cart') do %>
with (in the application helper)
def hidden_div_if(condition, attributes = {}, &block
if condition
attributes["style"] = "display: none"
end
content_tag("div", attributes, &block)
end
if that doesn't do it, then just do it this way
<% if #hide_checkout_button %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% else %>
<td><%= button_to 'Empty cart', cart, :method => :delete, :confirm => 'Are you sure?' %></td>
<% end %>
used
<div class="actions">
<% if not #hide_checkout_button %>
<%= button_to 'Checkout', new_order_path, method: :get, class: "checkout" %>
<% end %>
<%= button_to 'Empty cart', cart, method: :delete, data: { confirm: "Are you sure?" }, remote: true %>

Template error - ajax in rails 3

I have a nav menu with 2 tabs/links in the show.html.erb file, in UsersController.rb, I would like to use ajax to render different partial for the tabs.
In the show.html.erb I have a div named profile-data where I want to show the content.
So I do something like this:
The link structure:
<li><%= link_to "College friends", college_friends_path, :remote => true %></li>
<li><%= link_to "Highschool friends", highschool_friends_path, :remote => true %></li>
I define the routes:
match "college_friends" => "users#college_friends", :as => "college_friends"
match "highschool_friends" => "users#highschool_friends, :as => "highschool_friends"
And I define in my UserController.rb the necessary methods:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def college_friends
respond_to do |format|
format.js
end
end
def highschool_friends
respond_to do |format|
format.js
end
end
end
Last thing we have the JS files:
*college_friends.js.erb*
$('#profile-data').html("<%= escape_javascript(render(:partial => 'college_friends')) %>");
*highschool_friends.js.erb*
$('#profile-data').html("<%= escape_javascript(render(:partial => 'highschool_friends')) %>");
The partial code: _college_friends.html.erb
<% groups = #user.friends.group_by(&:college_name) %>
<% sorted_groups = groups.sort_by{|key, values| values.count}.reverse %>
<% sorted_groups.each do |collegename, friends| %>
<% next if collegename.blank? %>
<div class="contentbox">
<div class="box-header">
<h3><%= collegename %></h3>
<div class="meta-info">
<p><i class="icon-map-marker"></i> Malmö</p>
<p><i class="icon-user"></i><span class="count"> <%= friends.count %></span> vänner</p>
</div>
</div>
<ul class="friends-list">
<% friends.map do |friend| %>
<li><%= image_tag(friend.image) %>
<% end %>
</ul>
</div>
<% end %>
Nothing happens when I click the the links, and get this error in the console:
Started GET "/universitet_friends" for 127.0.0.1 at 2012-07-29 01:53:39 +0200
Processing by UsersController#universitet_friends as JS
Rendered users/_universitet_friends.html.erb (1.6ms)
Rendered users/universitet_friends.js.erb (3.1ms)
Completed 500 Internal Server Error in 7ms
ActionView::Template::Error (undefined method `friends' for nil:NilClass):
1: <% groups = #user.friends.group_by(&:college_name) %>
2: <% sorted_groups = groups.sort_by{|key, values| values.count}.reverse %>
3: <% sorted_groups.each do |collegename, friends| %>
4: <% next if collegename.blank? %>
app/views/users/_universitet_friends.html.erb:1:in `_app_views_users__universitet_friends_html_erb___1983680250475155079_70236040373720'
app/views/users/universitet_friends.js.erb:1:in `_app_views_users_universitet_friends_js_erb__1317362850668628869_70236044930260'
app/controllers/users_controller.rb:19:in `universitet_friends
Any help would be appreciated.
ActionView::Template::Error (undefined method `friends' for
nil:NilClass):
This is telling you that your #user variable is nil. This happened because when you went back to your controller for the AJAX request, you never actually set the #user variable. It does not persist between requests. You need to pass that variable during the ajax request. One way to do it is to add a user_id param to the ajax URL.
May be you can do something like this too
<%=link_to "Highschool friends", college_friends_path(:user_id => #user.id), :remote => true %>
The best way to do however would be to pass the user_id param to ajax url..you can fire the ajax request on link "on-click" event.

Threaded Comments - undefined method `children' for WillPaginate

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.

Resources