Loop through posts that is promote - ruby-on-rails

How to loop through post that are on promoted. I have a method in my post model that I can access. How would I call it in this instance. For example here are my methods my post model.
class Post < ApplicationRecord
def promoted?
subscriptions.present?
end
def self.promoted_posts
Post.joins(:subscriptions).where(:subscriptions => {:is_active => true})
end
def self.not_promoted_posts
Post.left_outer_joins(:subscriptions).where(:subscriptions => {:post_id => nil})
end
def self.ordered_posts
Post.promoted_posts + Post.not_promoted_posts
end
end
Here is my view. I would like to loop through all the posts that are promoted which is the method "def promoted?" in my model
<% #posts.take(6).each do |post| %>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-4">
<div class="featured-box">
<figure>
<%= link_to image_tag(post.images.first, class: 'img-fluid'), post %>
</figure>
<div class="feature-content">
<div class="product">
<p><%= post.category.name %> / <%= post.subcategory.name %></p>
</div>
<h4><%= link_to post.title, post %></h4>
<ul class="address">
<li>
Ad#: <%= post.ad_number %>
</li>
<li>
posted <%= time_ago_in_words(post.created_at) %> ago
</li>
<li>
<%= post.state%> , <%= post.city.downcase %>
</li>
</ul>
<div class="listing-bottom">
<h3 class="price float-left">$<%= post.price%></h3>
<%= link_to 'Feature Ad', post, class: 'btn-verified float-right', style: 'color: red;' %>
</div>
</div>
</div>
</div>
<% end %>

If you are desperately in need of using the promoted, you can try
Post.all.find_all(&:promoted?)
which is short notation of
Post.all.find_all do |post|
post.promoted?
end
which is kinda n+1 query and opting it while you can just use
Post.joins :subscriptions
is a fail.

Related

In Rails Erb how do I loop in desc order?

Hi I am trying to create a news feed but I want the newest post to display at the top. So basically I want to display in desc order. I'm sure I could come up with a solution for this but I was wondering if any one knows of the best and easiest way like if there is a method already supplied by rails to do this?
<h3 class="title">News Feed</h3>
<div class="news-content">
<% Post.all.each do |post| %>
<div class="post">
<div class="title"><%= post.title %></div>
<div class="date"><%= post.created_at.strftime('%b %-d') %></div>
<div class="content"><%= raw post.description %></div>
</div>
<% end %>
</div>
you make use of scope.
Create scope latest_first in Post model
class Post < ActiveRecord::Base
scope :latest_first, order('created_at DESC')
end
and use the scope in view
<h3 class="title">News Feed</h3>
<div class="news-content">
<% Post.latest_first.find_each do |post| %>
<div class="post">
<div class="title"><%= post.title %></div>
<div class="date"><%= post.created_at.strftime('%b %-d') %></div>
<div class="content"><%= raw post.description %></div>
</div>
<% end %>
</div>
you can give suitable name to scope based on its use
I would suggest to split the data-loading logic away into the controller ...
class PostsController < ApplicationController
def index
#posts = Post.order(id: :desc)
end
end
The controller layer specifies what data to load and how to do it. I also prefer to explicitly state the order using the ActiveRecord DSL. Then in your view you can just do ....
<h3 class="title">News Feed</h3>
<div class="news-content">
<% #posts.each do |post| %>
<div class="post">
<div class="title"><%= post.title %></div>
<div class="date"><%= post.created_at.strftime('%b %-d') %></div>
<div class="content"><%= raw post.description %></div>
</div>
<% end %>
</div>

How to access an instance variables id in the view

I'm using carrierwave to upload photos into my app, the photos have a 'belongs_to' relationship with each location, and the location has a 'has_many' relationship to the photos. Im my show page where the photos for the locations are uploaded they display as normal through a loop. However, in my index page I'm looping through my locations and want to display a photo for that location. The photos have the correct location_id, I'm just not sure on the syntax in the view to access that locations photo. What I would like to do is display one of the photos that correlates to a specific location, something like: #photo(location.id.last). Any help would be much appreciated, thanks in advance.
View
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<%= image_tag #photos, :size => '400x300', :class => 'img-responsive' %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
controller
class PagesController < ApplicationController
def index
#locations = Location.all
#photos = Photo.all
end
def about
end
def faqs
end
def blog
end
def whats_included
end
end
Accessing photo with the help of association:
location.photos.last.photo.url
HTML
<div class="row">
<!-- featured listings gallery -->
<% #locations.each do |location| %>
<% if location.featured == "true" %>
<div class="col-md-4 col-xs-6">
<div class="thumbnail">
<div class="overlay">
<!-- changing #photos to location.photos.last -->
<% if location.photos.any? and location.photos.photo.present? %>
<%= image_tag location.photos.last.photo.url, :size => '400x300', :class => 'img-responsive' %>
<% end %>
<div class="effect">
<div class="overlay-header">
<%= location.name %>
</div>
<div class="location-link">
<%= link_to "View Building", location_path(location) %>
</div>
</div>
</div>
<h3 class="display-box-caption">
<%= truncate(location.description, length: 100) %><%= link_to 'More', location_path(location), :class => 'more-info' %>
</h3>
</div>
<div class="col-md-12 property-link-container">
<%= link_to "View Building", location_path(location), :class=>"property-link" %>
</div>
</div>
<% end %>
<% end %>
</div>
Controller:
def index
#locations = Location.all
# no need to fetch photos now
# #photos = Photo.all
end
Photo Model
class Photo < ActiveRecord::Base
belongs_to :location
mount_uploader :photo, PhotoUploader
end
I see Sahil's post helped. Add .includes(:photos), to load Queries faster. In the future, will be super useful.
def index
#locations = Location.includes(:photos).all
end

Rails syntax error, unexpected keyword_ensure, expecting keyword_end

I'm trying to get two different types of tags working using the acts_as_taggable_on gem. I was following this link. I'm getting this error:
syntax error, unexpected keyword_ensure, expecting keyword_end
yntax error, unexpected end-of-input, expecting keyword_end
The error says the problem is line 92 of my show.html.erb, but when I put and <% end %> there, it doesn't fix it.
show.html.erb
<%- title "#{#artwork.title} — a #{#artwork.category.downcase} by Peter Bentley"%>
<% if user_signed_in? %>
<div class="row">
<div class="col-md-12">
<%= link_to 'Edit', edit_artwork_path(#artwork) %> |
<%= link_to 'Artworks Table', admin_path %>
</div>
</div>
<% end %>
<div class="row">
<div class="col-md-8">
<%= image_tag(#artwork.image.url, :class => 'img-responsive') %>
</div>
<div class="col-xs-12 col-md-4">
<p class="field-label">Title</p>
<h1><%= #artwork.title %></h1>
</div>
<div class="col-xs-6 col-sm-3 col-md-4">
<p class="field-label">Medium</p>
<h3><%= #artwork.medium %></h3>
</div>
<% unless #artwork.date.blank? %>
<div class="col-xs-6 col-sm-3 col-md-2">
<p class="field-label">Date</p>
<h3><%= #artwork.date.strftime("%b %d %Y") %></h3>
</div>
<% end %>
<% unless #artwork.height.blank? | #artwork.width.blank?%>
<div class="col-xs-6 col-sm-3 col-md-4">
<p class="field-label">Size</p>
<h3><%= #artwork.height %> x <%= #artwork.width %> in.</h3>
</div>
<% end %>
<div class="col-xs-6 col-sm-3 col-md-2">
<p class="field-label">Genre</p>
<h3><%= #artwork.genre %></h3>
</div>
<div class="col-xs-6 col-sm-3 col-md-2">
<p class="field-label">Category</p>
<h3><%= #artwork.category %></h3>
</div>
<% unless #artwork.availability.blank? %>
<div class="col-xs-12 col-sm-3 col-md-4">
<% if #artwork.availability == 'Available for purchase' %>
<p class="field-label">Availability</p>
<h3><%= #artwork.availability %></h3>
<%= link_to "Add to Inquiry List", root_path, class: "btn btn-primary" %>
<% else %>
<p class="field-label">Availability</p>
<h3><%= #artwork.availability %></h3>
<% end %>
</div>
<% end %>
<% unless #artwork.series.blank? %>
<div class="col-xs-6 col-sm-6 col-md-4">
<p class="field-label">Series</p>
<% #artwork.series.each do |series| %>
<span class="tags">
<%= link_to series.name, series_url(:series => series.name) %>
</span>
</div>
<% end %>
<% unless #artwork.tags.blank? %>
<div class="col-xs-6 col-sm-6 col-md-4">
<p class="field-label">Tags</p>
<% #artwork.tags.each do |tag| %>
<span class="tags">
<%= link_to tag.name, tagged_url(:tag => tag.name) %>
</span>
</div>
<% end %>
</div> <!-- end of 'row' div -->
<div class="fixed-prev-next">
<div class="btn-group" role="group" aria-label="...">
<%= link_to "Previous", #artwork.previous, :class => "btn btn-default" if #artwork.previous.present? %>
<%= link_to "Next", #artwork.next, :class => "btn btn-default" if #artwork.next.present? %>
</div>
</div>
<% end %>
artworks_controller.erb has
def index
if params[:tag]
#artworks = Artwork.tagged_with(params[:tag])
else
#artworks = Artwork.all
end
end
def tagged
if params[:tag].present?
#artworks = Artwork.tagged_with(params[:tag])
else
#artworks = Artwork.all
end
end
def series
if params[:series].present?
#artworks = Artwork.tagged_with(params[:series])
else
#artworks = Artwork.all
end
end
and private method that permits
:tag_list, :tag, :series_list, :series
artwork.rb has
acts_as_taggable
acts_as_taggable_on :tags, :series
What am I doing wrong?
You are failing to close 2 of your loops with an <% end %>.
<% unless #artwork.series.blank? %>
<div class="col-xs-6 col-sm-6 col-md-4">
<p class="field-label">Series</p>
<% #artwork.series.each do |series| %>
<span class="tags">
<%= link_to series.name, series_url(:series => series.name) %>
</span>
<%# Need end here, as illustrated on the next line. %>
<% end %>
</div>
<% end %>
<% unless #artwork.tags.blank? %>
<div class="col-xs-6 col-sm-6 col-md-4">
<p class="field-label">Tags</p>
<% #artwork.tags.each do |tag| %>
<span class="tags">
<%= link_to tag.name, tagged_url(:tag => tag.name) %>
</span>
<%# Need end here, as illustrated on the next line. %>
<% end %>
</div>
<% end %>
Take more care about how you're indenting your code. It matters and helps you to more easily prevent and debug syntax problems like this.

Reply to comment in the same page not in comments/new path, Rails 4

I have created commenting system to provide functions like creating comments and replying them.
I used http://www.sitepoint.com/nested-comments-rails/ guide. Worked just perfect. But in this example to reply to some comment it goes to other path, that is what I want to avoid.
Code so far:
Advertisement#show here I want to create reply to comment.
<%= comments_tree_for #comments %>
<h1>New comment</h1>
<%= render 'comments/form' %>
_comment.html.rb
<div class="well">
<h2><%= comment.title %></h2>
<p class="text-muted"><%= comment.root? ? "Started by" : "Replied by" %> <strong><%= comment.author %></strong> on
<%= l(comment.created_at, format: '%B, %d %Y %H:%M:%S') %></p>
<blockquote>
<p><%= comment.body %></p>
</blockquote>
<% from_reply_form ||= nil %>
<% unless from_reply_form %>
<% if comment.leaf? %>
<small class="text-muted">There are no replies yet - be the first one to reply!</small>
<% end %>
<p><%= link_to 'reply', new_comment_path(comment.id) %></p>
<% end %>
</div>
_form.html.erb
<%= form_for(#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 |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :advertisement_id, :value => #advertisement.id%>
<%= f.hidden_field :user_id, :value => current_user.id%>
<%= f.hidden_field :parent_id %>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: 'form-control', required: true %>
</div>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
Is there any trustworthy guide to help me ?
The link_to 'reply', new_comment_path(comment.id) line creates a hyperlink to new comment page and when clicked it takes you to next page to create the comment. Instead you can replace it with a div containing the form the toggles and submits new convo from the same page. Bootstrap comes handy here.
A Mock up of the idea: http://jsfiddle.net/bpya4fce/1/
You can build up using this idea. Hope this helps :)
P.S: Make sure that you fetch the variables required for the form in the action of view where you embed the form, i.e if you're embedding the form in show.html.erb, ensure the necessary variables are fetched in the show action/method of controller. In the earlier scenario, it'll be fetched in the new action of the CommentsController.
<div class="container">
<blockquote>
<h2>Posted Comment</h2>
Lorem Ipsum. You can reply to this below.
</blockquote>
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseOne">
Click to reply
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
### The comment form comes here ###<br/>
### render :partial => 'comment/form'
</div>
</div>
</div>
</div>
Not sure if this is what you wanted. Hope this example code gives you some idea.
Be sure to complete the code and test it :)
_comment.html.rb
<% from_reply_form ||= nil %>
<% unless from_reply_form %>
<% if comment.leaf? %>
<small class="text-muted">There are no replies yet - be the first one to reply!</small>
<% end %>
<!-- HERE adding a hidden DIV that contains a form. -->
<div class='hidden-reply-form-<%= comment.id%>'>
<%= render partial: 'comments/form', locals: {comment: Comment.new} %>
</div>
<p><%= link_to 'reply', new_comment_path(comment.id), class: 'reply', id: comment.id %></p>
<% end %>
</div>
<script>
// HERE use reply link to toggle the hidden div.
$(function(){
$(".reply").click(function(){
// toggle replying div.
// .....
});
})
</script>

Create a link from a div - Ruby on Rails

Currently I have a text link within the div that links correctly <%= link_to 'Show', profile %>. I have read that the below is the proper way to turn a div into a link
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
Though when I apply that to my block it gives me a undefined local variable or method 'profile'
<%= link_to profile do %>
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
<% end %>
My original block without the attempt at linking:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to 'Show', profile %>
</div>
</div>
<% end %>
</div>
My Controller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy, :id]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
#...
Your first example is problematic in many ways - you have links inside links. I'm not exactly sure what you're looking to output from this - but basically you need the
<%= link_to root_path do %>
<div>Hey!</div>
<% end %>
behavior to replace where you have <%= link_to 'Show', profile %>
Something along the lines of:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
<%= link_to profile do %>
<div>
fancy pants stuff here
</div>
<% end %>
</div>
</div>
<% end %>
</div>
If you can give me some guidance on what you want in the div I can post you some code to achieve that, I'm just not clear on what you are looking for exactly.
Another example could be (if you wanted more of the pieces to fall inside that <div></div>:
<div id="profiles" class="transitions-enabled">
<% #profiles.each do |profile| %>
<div class="box panel panel-default">
<div class="panel-body">
<%= link_to profile do %>
<div>
<%= image_tag profile.image.url(:medium) %>
<%= profile.artist %><br/>
... more fancy pants stuff here ...
</div>
<% end %>
</div>
</div>
<% end %>
</div>

Resources