Combining Multiple Models Into 1 View Rails - ruby-on-rails-3

I am a beginner working on a RoR app that allows users to update their resume with experiences and education. I have two models for these different items and would like to display them together in chronological order. I want to know how to set this up in my profile controller and view.
I'd like to adopt this same practice to a separate part of the app that will combine post and discussion items from users in the same way. However, currently, my focus is on the experience and education portion.
profiles/show.html.erb:
<% if #experiences.any? or #educations.any? %>
<div class="postExpOuter">
<% #experiences.each do |experience| %>
<div class="postExp">
<div>
<h2><%= experience.position %></h2>
<h3><%= experience.company %> | <%= experience.location %></h3>
<h4>
<%= experience.start_month %> <%= experience.start_year %>
<% if experience.end_year %>
<%= " - " + experience.end_month %> <%= experience.end_year %>
<% else %>
<span> - Present</span>
<% end %>
</h4>
</div>
</div>
<% end %>
<% #educations.each do |education| %>
<div class="postExp">
<div>
<h2><%= education.degree %></h2>
<h3><%= education.school %></h3>
<h4>
<% if education.end_year %>
<span>Class of </span><%= education.end_year %>
<% else %>
<%= education.start_year %><span> - Present</span>
<% end %>
</h4>
</div>
</div>
<% end %>
</div>
<% end %>

just hacked in my browser, don't know if it works directly:
<%- (#experiences.to_a + #educations.to_a).sort_by(&:end_year).each do |item| -%>
<%- if item.is_a? Experience -%>
your markup here...
<%- else -%>
your other markup here...
<%- end -%>
<%- end -%>
haven't written ERB since... uhh, long. basically it's just the following: merge the 2 ActiveRecord-Relations as Arrays into one big Array, sort them by the timestamp you want (you may add .reverse at the end if you want). While iterating through the list, check the type of object you have.
Hope this helps.

profiles_controller.rb:
class ProfilesController < ApplicationController
def show
#user = User.find_by_profile_name(params[:id])
if #user
#posts = #user.posts.all(:order => "created_at DESC", :limit => 3)
#experiences = #user.experiences.all(:order => "start_year DESC")
#educations = #user.educations.all(:order => "start_year DESC")
#items = (#experiences.to_a + #educations.to_a).sort_by(&:start_year).reverse[0,3]
render action: :show
else
render file: 'public/404', status: 404, formats: [:html]
end
end
end
profiles/show.html.erb:
<% if #items.any? %>
<div class="postExpOuter">
<% #items.each do |item| %>
<% if item.is_a? Experience %>
<div class="postExp">
<div>
<h2><%= item.position %></h2>
<h3><%= item.company %> | <%= item.location %></h3>
<h4>
<%= item.start_month %> <%= item.start_year %>
<% if item.end_year %>
<%= " - " + item.end_month %> <%= item.end_year %>
<% else %>
<span> - Present</span>
<% end %>
</h4>
</div>
</div>
<%- else -%>
<div class="postExp">
<div>
<h2><%= item.degree %></h2>
<h3><%= item.school %></h3>
<h4>
<% if item.end_year %>
<span>Class of </span><%= item.end_year %>
<% else %>
<%= item.start_year %><span> - Present</span>
<% end %>
</h4>
</div>
</div>
<% end %>
<% end %>
</div>
<% end %>

Related

yield is not working in partials other than application.html.erb

Here I have a requirement to use yield in a partial other than application.html.erb , when I try this in partial it was showing me the blank value and if I try the yield in application.html.erb it was showing the value.
application.html.erb
body>
<div id="main-container">
<%= content_for?(:page_header) ? yield(:page_header) : (render :partial => "/shared/home_header") %>
<div id="middle-container">
<%= yield %>
</div>
<div id="bottom-container">
<%= render "/shared/bottom_partial" %>
</div>
index.html.erb
<% content_for :page_header do %>
<%= render :partial => "/shared/employer_header" %>
<% end %>
<% content_for :page_name do %>
<p>My Account</p>
<% end %>
<div>
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx
</div>
/shared/_employer_header.html.erb
<div class="heading" >
<%= yield(:page_name) %>
</div>
When I am trying like above I am getting blank value in yield :page_name in employer header if I try the yield :page name in application.html.erb I am getting the value.Can any one help me to sort this out.Thank'U'.
Swap the order of your two content_fors so the :page_name is defined before the partial is rendered.
index.html.erb
<% content_for :page_name do %>
<p>My Account</p>
<% end %>
<% content_for :page_header do %>
<%= render :partial => "/shared/employer_header" %>
<% end %>

link_to current page rails

I was wondering what the syntax is to link to an attribute on the same page
I have a list of dates
<ul>
<% #response.each_pair do |date, movie| %>
<li><%= link_to date_format(date), date, :class => 'scroll_to' %></li>
<% end %>
</ul>
These then have movies underneath each date like so
<% #response.each_pair do |date, movie| %>
<h3 class="resultTitle fontSize13">Available on <%= date_format(date) %></h3>
<% movie.each do |m| %>
<div class="thumbnail clearfix">
<img class="pull-left" src=<% if m.image_link %> <%= m.image_link %> <% else %> "/assets/noimage.jpg" <% end %>>
<div class="caption pull-right">
<%= link_to m.name, m.title_id, :class => 'resultTitle fontSize11' %>
<p class="bio"><%= m.bio %></p>
<p class="resultTitle">Cast</p>
<p class="bio"><%= m.cast.join(", ") unless m.cast.empty? %></p>
<%= link_to "Remind me", reminders_path(:title_id => m.title_id), :method => :post, :class => 'links button' %>
</div>
</div>
<% end %>
<% end %>
What i would like to achieve is that when a user clicks on a date in the list then it will take them to that date with movies on the same page
My attribute for each date is
"release_date"
Do i need to link to that, maybe a piece of Jquery aswell to scroll down to that date? or would it jump to the date in one step?
Any advice appreciated, I have linked to other pages before but not the same page like this
EDIT
I have tried this but the page just re renders
<li><%= link_to date_format(date), params.merge(:release_date => 'release_date'), :class => 'scroll_to' %></li>
Am i on the right track?
Thanks
All you need is to give your date a unique identifier and link to that in you list. For instance below we give the h3 for each date an id relative to the date object. The browser knows how to handle internal links and will simply jump to the corresponding identifier. Notice how the id of the field you're linking to gets appended to the end of the url when you click on the link.
<ul>
<%- index = 0 %>
<% #response.each_pair do |date, movie| %>
<%- index += 1 %>
<li><%= link_to date_format(date), "##{index}", :class => 'scroll_to' %></li>
<% end %>
</ul>
<%- index = 0 %>
<% #response.each_pair do |date, movie| %>
<%- index += 1 %>
<h3 class="resultTitle fontSize13" id="<%= index %>">Available on <%= date_format(date) %></h3>
<% movie.each do |m| %>
<div class="thumbnail clearfix">
<img class="pull-left" src=<% if m.image_link %> <%= m.image_link %> <% else %> "/assets/noimage.jpg" <% end %>>
<div class="caption pull-right">
<%= link_to m.name, m.title_id, :class => 'resultTitle fontSize11' %>
<p class="bio"><%= m.bio %></p>
<p class="resultTitle">Cast</p>
<p class="bio"><%= m.cast.join(", ") unless m.cast.empty? %></p>
<%= link_to "Remind me", reminders_path(:title_id => m.title_id), :method => :post, :class => 'links button' %>
</div>
</div>
<% end %>
<% end %>
For the added JQuery transition you can replace
<li><%= link_to date_format(date), "##{index}", :class => 'scroll_to' %></li>
with
<li><%= link_to_function date_format(date), "$('html, body').animate({scrollTop:$('##{index}').offset().top }, 'slow');", :class => 'scroll_to'%></li>
The above isn't exactly a DRY approach, but the important thing to abstract out of that is that you're linking to a unique ID elsewhere on the page and not the code itself.

RoR: why aren't my microposts showing up?

Here is the users show view where they are supposed to show up. ..
edit (I have updated this post slightly you can see it at RoR: How can I get my microposts to show up?)
<section>
<div id= "purchases">
<%= render 'shared/micropost_form_purchase' %>
</div>
<div id="sales">
<%= render 'shared/micropost_form_sale' %>
</div>
</section>
<div id="purchases list">
<ol class="microposts">
<%= render #purchases unless #purchases.nil? %>
</ol>
</div>
<div id="sales list">
<ol class="microposts">
<%= render #sales unless #sales.nil? %>
</ol>
</div>
so the forms (partials) are loading fine, but then when I make a post, in either one, neither the purchases list nor the sales list shows up. I checked the database and they are being created along with an entry in the column indicating kind (either sale or purchase)
Here are the forms:
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
also, here is the show part of the users_controller.rb
def show
#user = User.find(params[:id])
#micropost=Micropost.new
#microposts = #user.microposts.paginate(page: params[:page])
end
and here is the show part of the microposts_controller.rb
def show
#micropost = Micropost.find(params[:id])
#microposts = Micropost.where(:user_id => #user.id)
#purchases = #microposts.where(:kind => "purchase")
#sales = #microposts.where(:kind => "sale")
end
can anyone help me out? anything else i need? hmmm
First, just to be sure you are getting the results you want, you should try something like this in your view
<%= #sales %>
This should be a hash of the results you want. Then, if that looks good, you want to do something like this
<div id="sales_list">
<ol class="microposts">
<% if #sales.any? %>
<% #sales.each do |sale| %>
<li><%= sale %></li>
<% end %>
<% end %>
</ol>
</div>
And repeat for purchases

Rails 3 Assign A Container Div Within Loop

say I'm looping through an array of products, how would I go about assigning a container div within that loop. For instance I want output like so:
<div class="page">
<p>product1</p>
<p>product2</p>
<p>product3</p>
<p>product4</p>
</div>
<div class="page">
<p>product5</p>
<p>product6</p>
<p>product7</p>
<p>product8</p>
</div>
I tried something like this:
<% #products.each_with_index do |product, index| %>
<% if index%4 == 0 %>
<div class="page">
<%end%>
<p><%= product.data %>
<% if index%4 == 0 %>
</div>>
<%end%>
<% end %>
But as expected it will only surround every 4th product with the container. I'm thinking that I'm going to need two loops in order for this to work, but how can I do this without duplicating data?
Edit
When using alternatives to each_with_index is there any way to keep a track of the index using this method? There are also some conditional attributes that get set based on the index value.
For example:
style=<%= index == 0 ? "top:5px;" : ""%>
<% #products.each_slice(4) do |slice| %>
<div class="page">
<% slice.each do |product| %>
<p><%= product.data %></p>
<% end %>
</div>
<% end %>
Another approach:
<% while group = #products.take 4 %>
<div class="page">
<% group.each do |product| %>
<p><%= product.data %></p>
<% end %>
</div>
<% end %>
The Rails method to split an array into groups of equal size is ary.in_groups_of(number)
<% #products.in_groups_of(4, false) do |group| %>
<div class="page">
<% group.each do |product| %>
<p><% product.data %></p>
<% end %>
</div>
<% end %>
Much nicer in Haml :)
- #products.in_groups_of(4, false) do |group|
.page
- group.each do |product|
%p= product.data
You can get the absolute product index with #products.index(product) or the group index with
<% #products.in_groups_of(4, false).each_with_index do |group, group_index| %>
<div class="page">
<% #products.each_with_index do |product, index| %>
<p><% product.data %></p>
<% if index % 4 == 3 %>
</div><div class="page">
<% end %>
<% end %>
</div>
(edit: forgot my end tag!)

Rails3 fields_for on text Hash: not working as expected

I have a rails3 form that allows the user to edit a list of answers, as part of an assessment.
I use a fields_for loop to generate each text input:
app/models/assessment.rb :
class Assessment < ActiveRecord::Base
serialize :answers, Hash # answers is a t.text field used to store all answers.
end
app/view/assessments/new.html.erb :
<p>Initialized answers: <%= #assessment.answers %></p>
<% item_counter = 0 %>
<% form.fields_for :answers do |answer_fields| %>
<% item_id = "item" + item_counter.to_s %>
<% item_counter = item_counter + 1 %>
<div class="field">
<%= answer_fields.label "the appropriate question, omitted for brevity" %>
<br/>
<% #assessment.answers[item_id] = "" %>
<%= answer_fields.text_field item_id, :value => #assessment.answers[item_id] %>
</div>
<% end %>
PROBLEM: The fields_for loop does zero iteration, no field gets printed.
( despite "Initialized answers:" showing correctly: {"a"=>143, "b"=>42} )
This should do. Tested locally.
<p>Initialized answers: <%= #assessment.answers %></p>
<% #assessment.answers.each do |key, value| %>
<%= form.fields_for :answers, #assessment.answers[key] do |answer_fields| %>
<div class="field">
<%= answer_fields.label key %>
<br/>
<%= answer_fields.text_field key, :value => value %>
</div>
<% end %>
<% end %>
Turns Hash to OpenStruct object solved my problem.
<% form.fields_for :answers, OpenStruct.new(answers) do |answer_fields| %>
<% item_id = "item" + item_counter.to_s %>
<% item_counter = item_counter + 1 %>
<div class="field">
<%= answer_fields.label "the appropriate question, omitted for brevity" %>
<br/>
<% #assessment.answers[item_id] = "" %>
<%= answer_fields.text_field item_id, :value => #assessment.answers[item_id] %>
</div>