Displaying the last posts image - ruby-on-rails

I am trying to show the image belonging to the last post at the top of my page
with this code:
<%= image_tag #postlast.last.image %>
Instead it shows the correct image but beside every post.
My index function looks like this:
def index
#posts = Post.order("created_at desc")
#postlast = Post.order("created_at DESC").limit(1)
end
Here is the full view:
<%= image_tag #postlast.last.image %>
<%= div_for(post) do %>
<div class="description">
<%= link_to (post.title), post %>
</div>
<div class="description2">
<%= time_ago_in_words(post.created_at) %> ago
<div class="floatright">
#Questions #Answers
</div>
</div>
<% end %>
Any help is appreciated!

Related

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

Error: param is missing or the value is empty:retweet

I am new to Rails. I want to pass parameters to DB via controller, but I receive this error param is missing or the value is empty:retweet. I think the problem is the way of passing parameters in view.
Here is the view
<% for #p in #posts %>
<div class="panel panel-default post-panel">
<div class="panel-body row">
<div class="col-sm-1">
<img src="/avatar.png" class="rounded-img" height="50px" width="50px">
</div>
<div class="col-sm-11">
<p class="post-title"><%= User.find(#p.user_id).username %> <span class="post-creation">- <%= #p.created_at.to_formatted_s(:short) %></span></p>
<p class="post-content"><%= #p.content %></p>
</div>
<div class="col-sm-12">
<p class="post-links">
<span class="glyphicon glyphicon-comment g-links" aria-hidden="true"></span>
**<%= form_for Retweet.new do |f| %>
<%= hidden_field_tag current_user.id, (:user_id) %>
<%= hidden_field_tag #p.id, (:post_id) %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
And here is the Controller
def new
#retweet = Retweet.new
end
def create
#retweet = Retweet.new(post_params)
redirect_to(:back)
end
private def post_params
params.require(:retweet).permit(:user_id, :post_id)
end
end
You should read up some tutorials on basic REST controllers in Rails. Your create action didn't save the retweet.
def create
#retweet = Retweet.new(post_params)
if #retweet.save
redirect_to(:back)
else
render action: 'new'
end
end
Edit: Just noticed your form is all wrong:
<%= form_for Retweet.new do |f| %>
<%= f.hidden_field :user_id, current_user.id %>
<%= f.hidden_field :post_id, #p.id %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
Mind you that you shouldn't allow settign the user_id like this, it is very easy to change it and thus mess around with your data. Instead you should add this to retweet#create:
#retweet.user = current_user

Combine 2 models into one array, paginate, and force 1 partial

I want to combine data from two different models, combine it into one array and use the will_paginate gem to paginate the results in my view on that collection. I'm already using require 'will_paginate/array' to allow for a normal, non-ActiveRecord array and its all working properly.
My problem is that its using two different partials to render the entries based on which model the data originated from. How do I force it render one specific partial?
controller
def sample_action
page = params[:page] || 1
#collection = []
#car.messages.select {|msg| #collection << msg}
Alerts.where(car_id: #car.id).select {|alerts| #collection << alerts}
#collection = #collection.sort{|a,b| b[:created_at] <=> a[:created_at]}
#collection = #collection.paginate(:page => page, :per_page => 30)
respond_to do |format|
format.html { render :sample_action }
end
end
view
<% if #collection.count > 0 %>
<div class="row">
<div class="col-xs-12">
<div id="car-alerts" class="car-alerts-all">
<%= render #collection -%>
</div>
</div>
</div>
<%= will_paginate #collection -%>
<% else %>
<p class="no-alerts-message">Your car is healthy</p>
<% end %>
car partial
Car - <%= collection.id %>
<br>
alert partial
Alert - <%= collection.id %>
<br>
I would use the fact that you basically just want to output the model name and do this:
<% if #collection.count > 0 %>
<div class="row">
<div class="col-xs-12">
<div id="car-alerts" class="car-alerts-all">
<%- #collection.each do |obj| -%>
<%= obj.class.to_s -%> - <%= obj.id %>
</div>
</div>
</div>
<%= will_paginate #collection -%>
<% else %>
<p class="no-alerts-message">Your car is healthy</p>
<% end %>
but it would break easily if you wanted to add labels different to class names.
You need to iterate over each item in the collection and have a conditional based on the model type, so for example:
<div id="car-alerts" class="car-alerts-all">
<% #collection.each do |car_or_alert| %>
<%=
if car_or_alert.is_a?(Alert)
render :alert #you need to add locals here as well, but it unclear what locals you are using
else
render :car #see above
end %>
<% end %>
</div>
Turns out it was as simple as setting the partial from render
<% if #collection.count > 0 %>
<div class="row">
<div class="col-xs-12">
<div id="car-alerts" class="car-alerts-all">
<%= render collection: #collection, partial: 'car/partial_name' -%>
</div>
</div>
</div>
<%= will_paginate #collection -%>
<% else %>
<p class="no-alerts-message">Your car is healthy</p>
<% end %>
This being the key change -
<%= render collection: #collection, partial: 'car/partial_name' -%>

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

will_paginate - don't show page entries info if collection is empty or less than per-page param

Let's say I have a controller action that creates the WillPaginate collection:
#comments = WillPaginate::Collection.new(#page_num, 15, #comments.length).concat(comments_to_paginate)
Then in my view:
<div class="pag">
<div clas="page_info">
<%= page_entries_info #comments %>
</div>
<%= will_paginate #comments, :container => false %>
</div>
Now what I want to do is to NOT show the page_entries_info output if (1) there are no comments and (2) if the number of entries (eg, 7) is less than the per page limit (15).
How would you go about handling this?
You just need to guard your page_entries_info with the conditions you wish
For example
<div class="pag">
<% if #comments.length > 0 && #comments.total_pages > 1 %>
<div class="page_info">
<%= page_entries_info #comments %>
</div>
<% end %>
<%= will_paginate #comments, :container => false %>
</div>
Or you can put this in your controller and keep your view a little cleaner, also letting you have one variable to reuse if you need the same guard around other parts of view code.
#comments = WillPaginate::Collection.new(#page_num, 15, #comments.length).concat(comments_to_paginate)
#show_pagination = #comments.length > 0 && #comments.total_pages > 1
Then in the view:
<div class="pag">
<% if #show_pagination %>
<div class="page_info">
<%= page_entries_info #comments %>
</div>
<% end %>
<%= will_paginate #comments, :container => false %>
</div>
If you can deal with the extra div, then this should also work
<div class="pag">
<div class="page_info">
<%= page_entries_info(#comments) if #show_pagination %>
</div>
<%= will_paginate #comments, :container => false %>
</div>

Resources