How to show spree product variant images only? - ruby-on-rails-4

Right now I've the following piece of code, which retrieves all images attached to Spree products.
<% #product.images_by_variant.each do |variant_id,images| %>
<ul class="gallery gallery-<%= variant_id %>" data-variant="<%= variant_id %>">
<% images.each do |image| %>
<li>
<%= image_tag(image.attachment.url(:single)) %>
</li>
<% end %>
</ul>
<% end %>
However, there are also images displayed that represent all variants. I want to hide those.
How can I only show variant (different colors for example) for products?
Cheers!

I found the solution. In the products_controller_decorator.rb, I added the following piece of code to the show method:
variants = #product.variants
if variants.blank?
#variants = #product
elsif variants.length > 1
#variants = variants.reject {|variant| variant.is_master? }
end
In the view I rendered the following partial:
<% if #variants == #product %>
<%= render partial: 'product_single/product_gallery', locals: {variant: #product} %>
<% else %>
<% #variants.each do |variant| %>
<%= render partial: 'product_single/product_gallery', locals: {variant: variant} %>
<% end %>
<% end %>

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

How do you use Active Record Enum Radio Buttons in a form?

In my app, there is a comment section on articles. I'd like the user to have the ability to comment with 3 different options. To activate this, I am using an Active Record Enum. Please note that the comment sections is nested under the articles.
resources :articles, only: [:index, :show] do
resources :comments
end
Migration:
class AddEnumToCommentModel < ActiveRecord::Migration
def change
add_column :comments, :post_as, :integer, default: 0
end
end
Comment model:
enum post_as: %w(username, oneliner, anonymous)
I attempted to add this to the content view, but lost. I am guessing I also have to do something in my controller but not sure.
Attempted view :
<%= form_for([#article, #comment]) do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<h3>Fill in your comment</h3>
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="post_as">
<h3> Choose how you want to post your comment :</h3>
<%= f.input :content, post_as: ???, as: :radio %>
</div>
<br>
<div class="actions">
<%= f.submit %>
</div>
<br>
<% end %>
Rails creates a class method using the pluralized attribute name when you use enum. The method returns a key value pair of strings you've defined and what integers they map to. So, you could do something like this:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label post_as.to_sym %>
<% end %>
There's also collection_radio_buttons, which is more succinct than the other options.
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first %>
Those last two arguments specify how to get the input's value and label text. In your example Comment.post_as produces a hash of enum key names to the underlying integer, so we can grab those using :second for the integer and :first for the name — easy!
Here's what that produces:
<input type="radio" value="0" name="comment[post_as]" id="comment_post_as_0">
<label for="comment_post_as_0">username</label>
# Etc.
You can also customize the HTML by passing a block, which is my preferred way to create enum radio buttons with clickable labels:
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first do |b|
b.label { b.radio_button + b.text }
end %>
An addition to xxyyxx's answer, if you want the labels to be clickable as well:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label "#{:post_as}_#{post_as.parameterize.underscore}", post_as %>
<% end %>
In the view instead of
<%= f.input :content, post_as: ???, as: :radio %>
you could have
<%= f.radio_button(:post_as, "username") %>
<%= label(:post_as, "Username") %>
<%= f.radio_button(:post_as, "oneliner") %>
<%= label(:post_as, "Oneline") %>
<%= f.radio_button(:post_as, "anonymous") %>
<%= label(:post_as, "Anonymous") %>
Source: http://guides.rubyonrails.org/form_helpers.html#radio-buttons

Rails: Render for nested forms

I have a nest form that is working great. The form is basically a customer with addresses.
I am trying to render a partial at both the customer and address level to indicate who created each record and who was the last person to update the record.
My view code is:
<%= form_for(#customer) do |f| %>
<%= render 'cust_fields', f: f %>
<%= render 'layouts/audit', audit: #customer %>
<strong>ADDRESSES:</strong>
<hr />
<%= f.fields_for :addresses do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: :addresses %>
<% end %>
<% end %>
The code in question is <%= render 'layouts/audit', audit: :addresses %>
This is throwing the the error:
undefined method `created_by' for :addresses:Symbol
I have tried to change :addresses to #customer.addresse but that doesn't work either. Why?
My partial code is:
<% created_user = User.find(audit.created_by) %>
<% updated_user = User.find(audit.updated_by) %>
<div class="row audit-info">
<small>
<div class="pull-left">
Created by: <%= created_user.name %>
</div>
<div class="pull-right">
Last updated by: <%= updated_user.name %>
</div>
</small>
</div>
Both the customers and addresses table have created_by and updated_by columns.
Any help would be much appreciated.
I was able to get this working by introducing the following code in my view:
<% for i in 1..#customer.addresses.size %>
<%= f.fields_for #customer.addresses[i-1] do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[i-1] %>
<% end %>
<% end %>
Actually, the above didn't work since I was double counting the children records.
What did work (after some more research) was the following:
<%= f.fields_for :addresses do |a| %>
<div class="deleterow">
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[a.index] %>
</div>
<% end %>
The key was using a.index, which can be seen on line 4.

Conditioning based on checkbox status

When a potential User is editing their Profile, they have an option to show/hide some information from public view. I did that with
<div class="field">
<%= f.text_field :contact %>
<%= f.select(:contact_type_id, ContactType.all.map {|l| [l.name, l.id]}) %>
<%= f.check_box :visible %>
<%= f.label :visible, "Vidljivo" %>
<%= f.link_to_remove "Izbriši kontakt" %>
</div>
in a partial that's called in the view like this
<%= f.fields_for :contacts do |l| %>
<%= render 'contacts_form', f: l %>
<% end %>
What I now want is to display on a public profile page only that information that the User marked as visible, and I tried it through a different partial
<div class="field">
<% if :visible == true %>
<%= f.text_field :contact %>
<% end %>
</div>
called from
<%= f.fields_for :contacts do |l| %>
<%= render 'contacts_show', f: l %>
<% end %>
but it doesn't work. I tried tons of variations, but it all came down to guessing the right syntax. How do I display only those entries which visibility is marked as "true"?
Why are you displaying the public profile as a form? If you only want to show the information you can iterate over the contact information of the user where the contact type is visible.
I solved it by using a different approach. In my user controller I defined an instance variable #visible and passed it the array consisting of all database entries that have visible parameter set to true. Then I used #visible.each in the view to print the desired content.

Rails 4.0 link_to overlaying an image with a link

I have a thumbnail image that links to a blog post entry which is accompanied by a text title. The CSS shades the image slightly and when the user hovers over the image, it re-sizes the image slightly. The user can click on the title or on the thumbnail to take them to the entry.
I cannot get the overlay tag here:
to be generated within rails link_to
<%= link_to(:class=>"overlay overlay-primary", id: entry) %>
The image is part of a figure
<figure class="entry-thumbnail">
<!-- to disable lazy loading, remove data-src and data-src-retina -->
<% if entry.cover_photo_link.blank? %>
<%= image_tag "placeholder.gif" %>
<% else %>
<%= image_tag entry.cover_photo_link %>
<% end %>
<!--fallback for no javascript browsers-->
<noscript>
<% if entry.cover_photo_link.blank? %>
<%= image_tag "placeholder.gif" %>
<% else %>
<%= image_tag entry.cover_photo_link %>
<% end %>
</noscript>
</figure>
The full thumbnail codes is in this gist
How do I get the image to link to use link_to render this?
The solution was simple. Putting the a blank "" in link_to did the trick
<%= link_to "", entry, :class => "overlay overlay-primary" %>
renders:
<a class="overlay overlay-primary" href="/entries/5"></a>
This worked well.