Multiple Loops on the same show page - ruby-on-rails

I have a page that displays a users videos that he has posted and also on the same page a users videos that he has voted on.
here is my controller
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
votes = #user.videos_with_votes("created_at desc").page(params[:page]).per_page(12)
end
end
Here is my view for my show page
<div id="videos">
<% #videos.each do |video| %>
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
<% end %>
</div>
I am confused on how to display the videos that the user has voted on in the same way that i am looping the users video posted?

Use an instance variable, e.g.
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
#voted_videos = #user.videos_with_votes("created_at desc").page(params[:page]).per_page(12)
end
end
<div id="voted_videos">
<% #voted_videos.each do |video| %>
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
<% end %>
</div>
If the display of videos and voted videos is the same than you can look to make this code:
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
a partial called _videos.html.erb that can be used for both #videos and #voted_videos.
Store this file (with the above code) in the same directory as the other view files
e.g.
<div id="voted_videos">
<% #videos.each do |video| %>
<% render "videos" %>
<% end %>
</div>
<div id="voted_videos">
<% #voted_videos.each do |video| %>
<% render "videos" %>
<% end %>
</div>

You need to use #votes instead of votes by itself. The # symbol shares the variable with the view layer so that you can do things with it (like loop over it).

there is a concept about instance variable and local variable in rails.
whenever you define a variable with # symbol that particular variable is an instance variable and is accessible across its views and partials.
for eg : #videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
here #videos is an instance variable and persists its instance across its scope.
whereas local variables have its scope limited to its loop/boundry. Local variables are preferably used in loops where after the execution of the loop the variable is Garbage Collected and we can again use the same variable name for storing different value.
In your case votes is not accessible in your view as its a local variable, and hence to use this variable in your view you need to define this variable as instance variable (as #votes).

Related

Where is the sessions hash in the Chrome Dev Tools?

I'm storing a counter in the sessions hash that gets incremented every time I call the index action in the Store controller.
I'm printing it out in the Store view, as shown in the code and screenshot.
I know I can "reset the counter" by deleting the cookie, shown in the screen shot. And I know I print the sessions hash on the server. But how do I see the sessions hash in the chrome dev tools?
store_controller.rb
class StoreController < ApplicationController
def index
#products = Product.order(:title)
session[:counter] ||= 0
session[:counter] += 1
end
end
store/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Your Pragmatic Catalog</h1>
<p><%= session[:counter] %></p>
<% p session %>
<% cache #products do %>
<% #products.each do |product| %>
<% cache product do %>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= number_to_currency(product.price) %></span>
<%= button_to 'Add to Cart', line_items_path(product_id: product) %>
</div>
</div>
<% end %>
<% end %>
<% end %>
screenshot
As described in Hartl's Rails Tutorial the sessions hash is encrypted so you wouldn't be able to view it in plain text from the browser.

displaying data from database in a partial

I'm pretty new to rails and I can't figure out how exactly to get data from the database and have it show up in a partial. So I have a question_form partial:
<h1>Add question here</h1>
<div class="row">
<div class="col-md-6">
<%= form_for(:question, url: questions_path) do |f| %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose question..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<!-- ref 398, 664 -->
<% end %>
</div>
</div>
I render it in my root_path (staticpages#home). It POSTs to a create action in a Questions controller which saves it to the database. I want to then display all of the questions submitted at once. I know I can do something like:
def show
#questions = Question.all
end
then iterate through #students in show.html.erb. But the problem is I don't want it in a separate page, I want it all to be shown on the homepage as well. How should I do this?
What about adding the instance variable to the show action for your StaticPagesController:
class StaticPagesController < ApplicationController
def show
#questions = Question.all
# ... Code to render pages/:page
end
And then iterate #questions on the view:
<% #questions.each do |question| %>
<%= question.content %>
<% end %>

Group posts by Year - Rails

I have model called "Shoes" that belongs to the a model called "History". I want to show all of the shoes in my History show.html.erb page, but I want to group them by their release date. (I have an attribute called release for that).
I'm using this example from Railscasts:
shoes_controller
def index
#shoes = Shoe.all(:order => 'release, name')
#release_year = #shoes.group_by { |t| t.release.beginning_of_year }
end
Shoes index.html.erb view
<% #release_year.each do |release, shoes| %>
<% shoes.each do |shoe| %>
<%= shoe.name %>
<% end %>
<% end %>
I want to be able to do this but on my History show.html page, how can i accomplish this?
What I have so far:
History show.html.erb
<% #history.shoes.each do |shoe| %>
<div class="shoe">
<%= shoe.name %>
</div>
<% end %>
Thanks.
Perhaps you may want to create a _shoes_by_year partial in the shoe views, and then render the shoe collection:
views/shoes/_shoe.html.erb
<div class=shoe>
<%= shoe.name %>
</div>
views/shoes/_shoes_by_year.html.erb
<% shoes_by_year.each do |release_year, shoes| %>
<div>
<h3><%= release_year.year %></h3>
<%= render 'shoes/shoe', collection: shoes %>
</div>
<% end %>
histories_controller.rb
def show
...
#shoes = #history.shoes.group_by { |shoe| shoe.release.at_beginning_of_year }
end
/views/history/show.html.erb
...
<%= render 'shoes/shoes_by_year', object => #shoes %>

rendering two partials into one (rails 3), am I doing this right?

I am using the Public_Activity gem to display the list of actions being performed on the website. I already have a main feed on the homepage but I would also like to include all of the activities that are being tracked using that gem.
Here's what I am trying to do inside the controller
class StaticPagesController < ApplicationController
def home
if signed_in?
#micropost = current_user.microposts.build
#feed_activities = PublicActivity::Activity.order("created_at desc")
#feed_posts = current_user.feed.without_review.paginate(page: params[:page])
#feed_items = #feed_posts + #feed_activities
end
end
Then in my view, this is how I'm trying to call it
<% if #feed_items.any? %>
<ol class="microposts">
<%= render partial: 'shared/feed_item', collection: #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
the _feed_item.html being called above is
<li id="<%= feed_item.id %>">
<br>
<% if #feed_activities? %>
<%= link_to activity.owner.name, activity.owner if activity.owner %> has posted
<% else %>
<div class ="gravatarhome"><%= link_to gravatar_for(feed_item.user), feed_item.user %></div>
<span class="user">
<%= link_to feed_item.user.name, feed_item.user %>
</span>
<span class="textname">shared this</span><span class="timestamp"> <%= time_ago_in_words(feed_item.created_at) %> ago.
</span>
<div class="FeedContent"><%= truncate(feed_item.content, :length=>150, :omission=>' ...(continued)') %>
<% if current_user?(feed_item.user) %>
<%= link_to "delete", feed_item, method: :delete,
confirm: "You sure?",
title: feed_item.content %>
<% end %><br>
<% end %>
</li>
However, I'm getting this error
NameError in Static_pages#home
Showing C:/app/views/shared/_feed_item.html.erb where line #5 raised:
undefined local variable or method `activity' for #<#<Class:0x6ef3b98>:0x60d50d8>
anyone know if there's a better way to do this and where the activity variable needs to be defined to get this to work?
Update: here's my application_controller that uses the gem
class ApplicationController < ActionController::Base
include PublicActivity::StoreController
The error have stated the problem, rails does not know which activity refer to.
Neither you have activity loaded in the controller, or it is associated to feed_item
Or not rails does not know which activity refer to
activity is a variable that is not defined in this partial, so it will give error.
If you want to loop all activities via collection, then you have to pass variable as collection while rendering the partial and calling using partial name like this:
<%= link_to feed_item.owner.name, feed_item.owner if feed_item.owner %> has posted
Replace activity by feed_item in your partial. It will solve your problem.

why does this form not take data from a model?

I would like to capture email addresses with this form:
I have decided to create a model only for this and use the views and controller for a different model that is serving only static assets (think: newsletter sign-up).
<%= form_for (#signup) do |f| %>
<% if #signup.errors.any? %>
<div id="error_explanation">
<p><%= pluralize(#signup.errors.count, "error") %> prohibited this post from being saved:</p>
<ul>
<% #signup.errors.full_messages.each do |user| %>
<li><%= user %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email_address %><br />
<%= f.email_field_tag :email_address %>
</div>
<div class="actions">
<%= f.submit %>
</div>
How do I get this form to work? I get undefined method signups_path for #<#<Class:0x00000004f1feb0>:0x00000004f09a98> exception, which is understandable (its looking for a SignupsController by convention).
But I want the form to display in a separate controller I call PagesController and send it to the Signup model.
Additional Info:
I tried passing url: pages_path in the form and get the same exception.
# view inside PagesController
<div class="four columns">
<%= render 'form' %>
</div>
#stub of model
class PagesController < ApplicationController
def index
#signup = Signup.new
end
def create
#signup = Signup.new(params[:signup])
end
end
try:
<%= form_for #sighup, :url => {:controller => :pages, :action => :index} do |f| %>
and I hope you didn't forget the
<% end %>

Resources