Coffeescript rails select one of two models - ruby-on-rails

I have two models in ruby,
#photos = Photo.all
#comments = Comment.all
#objects = #photos + #comments
I have in my html a button id"only-photo" and a button "only-comments", if i click on the first I want to select only the photos.
how can I do to only select #photos from #objects? in coffeescript
here is what i tried
<div id="list">
<% #objects.each do |l| %>
<% if l.class == "Photo"%>
<div id="photo" class="photo">
<%= render "shared/photo", :photo => l %>
</div>
...
</div>
<div id="filters">
<button id="only-photo">
</button>
...
</div>
then in Coffeescript I just do:
$("#filters").on "click", "#only-photo", ->
$("#list #comment").removeClass "active"
$("#list #photo").addClass "active"
BUT I am sure there is a more elegant way to do these things!
Can't we filter on a scope from coffeescript? or anything like this?
Thank you!

Try this:
<div id="list">
<% #objects.each do |l| %>
<div id="<%= l.class.to_s.downcase %>_<%= l.id %>" class="<%= l.class.to_s.downcase =%>">
<%= render "shared/#{l.class.to_s.downcase}", :photo => l %>
</div>
<% end %>
</div>
<div id="filters">
<button id="only-photo" class="filter" value="photo">
</button>
<button id="only-comment" class="filter" value="comment">
</button>
</button>
</div>
Coffee:
$("button.filter").on "click", ->
class_to_hide = $(this).attr('value')
$("."+class_to_hide).toggleClass('active')

Related

Rails 5 yield gives duplicate contents

I am figuring out why it showing duplicate data on the front page:
All I did is to use Rails collection rendering.
Here's my application.html.erb file:
<body>
<%= render 'layouts/navbar' %>
<!-- content -->
<main class="pt-5">
<div class="container">
<div class="row">
<%= render 'layouts/sidebar' %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</main>
</body>
</html>
Here's my index.html.erb file:
<div class="col-md-9">
<% if #contacts.blank? %>
<div class="alert alert-warning">
<strong>Record is empty!</strong>
</div>
<% else %>
<div class="card">
<div class="card-header"><strong>All Contacts</strong></div>
<table class="table">
<%= render #contacts %>
</table>
</div>
</div>
<% end %>
and here's my _contact.html.erb file:
<% #contacts.each do |contact| %>
<tr>
<td class="middle">
<div class="media">
<div class="media-left">
<a href="#">
<%= image_tag contact.gravatar, class: "media-object" %>
</a>
</div>
<div class="media-body">
<h4 class="media-heading"><%= contact.name %></h4>
<address>
<strong><%= contact.address %>, <%= contact.city %>, <%= contact.state %>, <%= contact.zip %></strong><br>
<%= contact.email %> | <%= contact.phone %> | <%= contact.mobile %>
</address>
</div>
</div>
</td>
<td width="100" class="middle">
<div>
<a href="#" class="btn btn-outline-secondary btn-circle btn-xs" title="Edit">
<i class="fa fa-edit"></i>
</a>
<a href="#" class="btn btn-outline-danger btn-circle btn-xs" title="Delete">
<i class="fa fa-times"></i>
</a>
</div>
</td>
</tr>
<% end %>
BTW, I am using Kaminari Gem for pagination. It works however the data shows twice.
Any idea?
UPDATES:
Here's my contacts controller:
class ContactsController < ApplicationController
def index
#contacts = Contact.page params[:page]
end
end
Here's the kaminari config file:
# frozen_string_literal: true
Kaminari.configure do |config|
config.default_per_page = 2
# config.max_per_page = 4
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.params_on_first_page = false
end
When you do <%= render #contacts %>, Rails will loop results from #contacts and render each one using _contact.html.erb, while embedding local variable contact in each one. You see contacts twice, because you loop twice: remove <% #contacts.each do |contact| %> from _contact.html.erb and it should work.

Rails, rendering after destroy

I have a Cart/show.html erb with that renders a partial called carts_row.html.erb
<p id="notice"><%= notice %></p>
</br>
</br>
<div class="cart-container">
<%=render 'carts_row'%>
</div>
</p>
In carts_row it's a shopping cart layout with forms to update quantity and destroy/remove item from your shopping cart.
<h1>Shopping Cart</h1>
<div class="shopping-cart">
<div class="column-labels">
<label class="product-image">Image</label>
<label class="product-details">Product</label>
<label class="product-price">Price</label>
<label class="product-quantity">Quantity</label>
<!-- adding update column to labels -->
<label class="product-update">Update</label>
<label class="product-removal">Remove</label>
<label class="product-line-price">Total</label>
</div>
<%if #cart.cart_items.size == 0%>
<div class="text-center">
<p>Looks like you have nothing in your cart! <%=link_to 'Add something to your cart', products_path%></p>
</div>
<%end%>
<br />
<br />
<%if #cart_items != nil%>
<%#cart_items.each do |item|%>
<div class="product">
<div class="product-image">
<%=image_tag(item.product.picture)%>
</div>
<div class="product-details">
<div class="product-title"><%=item.product.name%></div>
<p class="product-description"><%=item.product.description%></p>
</div>
<div class="product-price"><%=number_to_currency(item.product.price)%></div>
<%=form_for item, remote: true do |f|%>
<div class="product-quantity">
<%=f.number_field :quantity, value: item.quantity, min: 1, max: 8%>
<%=f.hidden_field :product_id, value: item.product.id%>
<!-- <input type="number" value="<%=item.quantity%>" min="1" max="8"> -->
</div>
<div class="product-update">
<%=f.submit 'Update', class: "update-product"%>
<!-- <%=f.hidden_field :product_id, value: item.product.id%> -->
<!-- <button class="update-product">
Update
</button> -->
</div>
<div class="product-removal">
<%= link_to "Remove", item, {data: {confirm: "Are you sure you wish to delete the product '#{item.product.name}' from your cart?"}, method: :delete, remote: true, class: "remove-product"}%>
<!-- <button class="remove-product">
Remove
</button> -->
<%end%>
</div>
<div class="product-line-price"><%=number_to_currency(item.product.price*item.quantity)%></div>
</div>
<%end%>
<%end%>
<br />
<br />
<!--Temporary solution until model methods are written -->
<% if #cart_items != nil%>
<!--subtotal variable -->
<%subtotal =#cart_items.collect {|item| item.quantity*item.unit_price}.sum%>
<!--subtotal + shipping cost -->
<%total=subtotal+15%>
<%end%>
<div class="totals">
<div class="totals-item">
<label>Subtotal</label>
<div class="totals-value" id="cart-subtotal"><%=subtotal%></div>
</div>
<div class="totals-item">
<label>Tax (5%)</label>
<div class="totals-value" id="cart-tax">Included!</div>
</div>
<div class="totals-item">
<label>Shipping</label>
<div class="totals-value" id="cart-shipping">15.00</div>
</div>
<div class="totals-item totals-item-total">
<label>Grand Total</label>
<div class="totals-value" id="cart-total">
<%=total%>
</div></div>
</div>
</div>
<div class="checkout-btn">
<button class="checkout">Checkout</button>
</div>
</div>
The update in the form goes to update.js.erb which has this
<% if #cart.errors.any? || #cart_item.errors.any? %>
alert("Not valid.");
<%else%>
$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text')%>")
$(".cart-container").html("<%= escape_javascript(render 'carts/carts_row')%>")
<%end%>
And destroy in the form has a same destroy.js.erb
<% if #cart.errors.any? || #cart_item.errors.any? %>
alert("Not valid.");
<%else%>
$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text')%>")
$(".cart-container").html("<%= escape_javascript(render 'carts/carts_row')%>")
<%end%>
The update renders the carts_row.html.erb form properly.
When I destroy an item it renders the page with empty products and a checkout total at the bottom. When I refresh the page the correct amount of products in the shopping cart is displayed and everything is where it should be!
How is the render of update correct but render of destroy incorrect???
My carts_item controller has these two methods for the forms:
def update
#cart = current_cart
# finding cart_items by cart_id
#cart_item = #cart.cart_items.find(params[:id])
# #cart_items.order(:id)
#cart_item.update_attributes(cart_item_params)
#cart_items = #cart.cart_items.order(:id)
# redirect 'cart_show_path'
end
def destroy
#cart = current_cart
#cart_item = #cart.cart_items.find(params[:id])
#cart_item.destroy
#cart_items = #cart.cart_items
end
You're destroying the item from cart, but not removing it from #cart.cart_items
Try doing this
def destroy
#cart = current_cart
#cart_item = #cart.cart_items.find(params[:id])
#Find the index of #cart_item
item_index = #cart.cart_items.index(#cart_item)
#Remove it from #cart.cart_items when its destroyed successfully
if #cart_item.destroy
#cart.cart_items.delete_at(item_index)
end
#cart_items = #cart.cart_items
end
Let me know if it works!
I figured out the problem. The problem was that I was using a <% if #cart_items != nil %> check in my view.
This always returns false, because ActiveRecord will always return an array!!!!!!!!!! Whether it has product objects in the #cart_items object or not.
After I changed this to test for empty arrays with #cart_items.empty?, then the page worked like I wanted it to.
Thanks kumar for your input.

Bootstrap/Rails - String Interpolation inside accordion

I've been struggling with string interpolation inside an HTML accordion. It's more a logic issue that I can't seem to figure out (fairly new to rails). The problem I have is that while the layout is fine, when I click to collapse any of the 3 collapsible panels they all collapse. (Because I only have 1 #collapse).
Outermost ERB
<div class="container-fluid">
<div class="row">
<div class="col-md-2 col-sm-3">
<h2>Categorias</h2>
<div class="panel-group" id="accordion">
<%= render partial: "categories/catalog", collection: #categories, as: :c %>
</div>
</div>
_catalog Partial
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
<%= c.name %>
<span class="badge">4</span>
</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
<% c.subcategories.each do |sc| %>
<div class="panel-body">
<a href="#">
<%= sc.name %>
</a>
</div>
<% end %>
</div>
</div>
Controller
def catalogo
#categories = Category.where("parent_id IS NULL")
unless params[:cat_id].blank?
#products = Product.where(category_id: params[:cat_id]).paginate(:page => params[:page], :per_page => 50)
else
#products = Product.all.paginate(:page => params[:page], :per_page => 50)
end
#categorieswparent = Category.where("parent_id IS NOT NULL")
end
Your IDs need to be unique. Instead of hard-coding id="collapse1", use the ID of the record:
id="collapse<%= sc.id %>"
Perform the same interpolation for the href of the <a> tag responsible for collapsing and expanding the accordion.
Use category id id="#collapse<%= c.id %>" to interpolate with element id in _catalog Partial.
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<%= c.id %>">
<%= c.name %>
<span class="badge">4</span>
</a>
</h4>
</div>
<div id="collapse<%= c.id %>" class="panel-collapse collapse in">
<% c.subcategories.each do |sc| %>
<div class="panel-body">
<a href="#">
<%= sc.name %>
</a>
</div>
<% end %>
</div>
</div>

Rails: Cannot get tabs to work with and kaminari

I have two tabs at the profile page: tab 1) my recipes, tab 2) my favorites.
Kaminari pagination works just fine when I go to the index page for recipes. However the pagination does not work properly at the profile page. When I click on next it does show me the next page, but the pagination bar disappears. So I cannot go back, unless I refresh the page.
Who can help me? Thank you in advance.
Profile controller:
class ProfilesController < ApplicationController
def show
#recipes = current_user.recipes.order("name").page(params[:recipes_page]).per(3)
#favorites = current_user.favorites.order("name").page(params[:favorites_page]).per(3)
end
end
Kaminari:
<% if #recipes.present? %>
<div class="apple_pagination" id="paginator-my-recipes">
<%= paginate #recipes, :remote => true, :param_name => :recipes_page %>
</div>
<% end %>
app/views/profiles/show.html.erb:
<div class="container is-small sand-color">
<div class="tabs">
<div class="your-recipes-btn">
<a class= "tab active" data-target= "#your-recipes">
<h4>Your recipes</h4>
</a>
</div>
<div class="your-favorites-btn">
<a class= "tab" data-target= "#your-favo">
<h4>Favorites</h4>
</a>
</div>
</div>
</div>
<div class="tab-content" id="your-recipes">
<div class="container is-small sand-color">
<% if #recipes.present? %>
<%= render #recipes %>
<% else %>
<h4 class="text-center">Create your own recipes</h4>
<% end %>
</div>
<% if #recipes.present? %>
<div class="apple_pagination" id="paginator-my-recipes">
<%= paginate #recipes, :remote => true, :param_name => :recipes_page %>
</div>
<% end %>
</div>
<div class="tab-content hidden" id="your-favo">
<div class="container is-small sand-color">
<% if #favorites.present? %>
<%= render #favorites %>
<% else %>
<h4 class="text-center">You don't have any recipes</h4>
<% end %>
</div>
<% if #favorites.present? %>
<div class="apple_pagination" id="paginator-my-favo">
<%= paginate #favorites, :remote => true, :param_name => :favorites_page %>
</div>
<% end %>
</div>
app/views/profiles/_favorites.html.erb
<div class="product">
<div class='product-upvote'>
<div class="product-arrow"></div>
<div class='product-count'>95</div>
</div>
<% if recipe.photo != nil %>
<%= cl_image_tag recipe.photo, height: 100, width: 150, crop: :fill, class: "product-image hidden-xs" %>
<% else %>
<% end %>
<div class='product-body'>
<%= link_to recipe_path(recipe) do %>
<h4><%= recipe.name %></h4>
<% end %>
<div class="summary dont-break-out">
<p><%= recipe.summary %></p>
</div>
<div class="recipes-info">
<div class="recipes-kitchen">
<p>Gang</p>
<h5> <%= recipe.course %> </h5>
</div>
<div class="recipes-kitchen">
<p>Keuken</p>
<h5> <%= recipe.kitchen %> </h5>
</div>
<div class="cooking-time">
<p>Kooktijd</p>
<h5><%= recipe.cooking_time %> min</h5>
</div>
<div class="created">
<p>Geplaatst op</p>
<h5><%= recipe.created_at.strftime('%d/%m/%Y') %> </h5>
</div>
</div>
</div>
</div>
app/views/profiles/show.js.erb:
$('#your-recipes').html('<%= escape_javascript render(#recipes) %>');
$('#paginator-my-recipes').html('<%= escape_javascript(paginate(#recipes, :remote => true).to_s) %>');
$('#your-favo').html('<%= escape_javascript render(#favorites) %>');
$('#paginator-my-favo').html('<%= escape_javascript(paginate(#favorites, :remote => true).to_s) %>');

passing dynamic variable to partial for rendering in a modal

I have the following Code on a partial that dynamically generates a list of associated steps to a pin. Both pins and steps have image(s). Users are able to add multiple steps to a pin and then this view dynamically generates a view of these steps. For each step there are associated image(s) which I'd like to pop-up as a modal. The challenge is I keep getting the following error:
"undefined local variable or method `step' for #<#:0x00000102f498d8>"
When I stub out rendering the partial, the modal appears basically blank but works. Any ideas How do I do this?
<div class="col-md-6">
<% (0..(Step.where("pin_id = ?", params[:id]).count)-1).each do |step| %>
<div class="col-md-12">
<div class="well">
<ul class="nav pull-right">
<% if current_user == #pin.user %>
<%= link_to edit_step_path((Step.where("pin_id = ?", params[:id]).fetch(step)), :pin_id => #pin.id) do %>
<span class="glyphicon glyphicon-edit"></span>
Edit
<% end %> |
<%= link_to Step.where("pin_id = ?", params[:id]).fetch(step), method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-trash"></span>
Delete
<% end %> |
<%= link_to new_step_image_path(:step_id => Step.where("pin_id = ?", params[:id]).fetch(step), :pin_id => #pin.id) do %>
Add
<span class="glyphicon glyphicon-picture"></span>
<% end %>
<% end %>
<% if StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count == 0 %>
<% else %>
| <a href="#StepImageModal" data-toggle="modal">
<span class="glyphicon glyphicon-picture"></span> (<%= StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count %> ) </strong>
</a>
<% end %>
</ul>
<strong> Step <%= step+1 %>
<p>
<%= Step.where("pin_id = ?", params[:id]).pluck(:description).fetch(step) %>
</p>
</div>
</div>
<%end %>
</div>
<div class="modal fade" id="StepImageModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal Header</h3>
</div>
<div class="modal-body">
<%= render :partial => 'pins/step_images',
:locals => { :step => step } %>
</div>
<div class="modal-footer">
Close
</div>
</div>
I don't get what you're trying to do here
Loop
As mentioned in the comments, you've got a loop which goes through your steps. However, outside the loop, you want to display the partial
The solution to your woes will either be to set an instance variable (not desired), or use another persistent data type. I'd do this:
#app/controllers/steps_controller.rb
def action
#step = {}
end
#app/views/steps/action.html.erb
<% (0..(Step.where("pin_id = ?", params[:id]).count)-1).each do |step| %>
<% #step[step.id.to_sym] = step.details %>
<% end %>
<%= render :partial => 'pins/step_images', :locals => { :step => #step } %>
unless
Some refactoring for you:
<% unless StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count == 0 %>
| <%= link_to "#StepImageModal", data: { toggle: "modal"} do %>
<span class="glyphicon glyphicon-picture"></span>(<%= StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count %> ) </strong>
<% end %>
<% end %>

Resources