Rails: Iterating with Uneven Columns - ruby-on-rails-4

I have a model, Friends, that I want to iterate in a view, but I'm having trouble with because I'm having to use uneven column widths.
Normally, if the column widths were constant, I would do some thing like this:
<% #user.friends.each do |friend|%>
<div class="col-md-6">
<%= friend.name %>
</div>
<% end %>
However, because of the layout I'm working with, I need to put an offset in the first column:
<div class="col-md-5 col-md-offset-1">
and I don't want the offset in the second column:
<div class="col-md-6">
How can I iterate through #user.friends with alternating column widths?

you can iterate through the list using each_with_index and add conditional css class based on odd/even value of the index
<% #user.friends.each_with_index do |friend, index| %>
<div class="<%= (index).even? ? 'col-md-5 col-md-offset-1' : 'col-md-6' %>">
<%= friend.name %>
</div>
<% end %>

how about
<% #user.friends.each_with_index do |friend, index|%>
<% if index == 0 %>
<div class="col-md-5 col-md-offset-1">
<%= friend.name %>
</div>
<% else %>
<div class="col-md-6"> #whatever offset u need
<%= friend.name %>
</div>
<%end%>

The following will give the 1st, 3rd, 5th, etc.. friend the offset.
<% odd = true %>
<% #user.friends.each do |friend|%>
<%= raw(odd ? '<div class="col-md-5 col-md-offset-1">' : '<div class="col-md-6">') %>
<%= friend.name %>
</div>
<% odd = !odd %>
<% end %>

Related

How to render another models form on another page?

Ok so Ive looked around at many answers posted on stackoverflow and many other sites because I know that this is a commonly asked question but I just cant seem to get it and would really appreciate it if someone could point me in the right direction. What Im trying to achieve here is really simple, Im trying to render a new form from another model, Post into my homepage, which is another controller that I created. So basically in my homepage it shows a list of all the recent Post that were created by users. Furthermore I wanted to user to be able to directly add a new Post from the homepage. Right now I have it displaying however clicking on the submit button does absolutely nothing.
Here is the form for POST
<div class="panel panel-primary">
<div class="container">
<div class="panel-heading">
<%= image_tag #post.user.avatar.url(:post_pic), class:"img-thumbnail" %>
<%= #post.user.name %>
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.file_field :avatar %>
</div>
</div>
</div>
<div class="panel-footer">
<div class="actions">
<%= f.submit %>
</div>
</div>
<% end %>
</div>
Here is my homepage controller
class HomeController < ApplicationController
def index
if user_signed_in?
#posts = Post.all
#post = current_user.posts.build
else
redirect_to new_user_registration_path
end
end
def create
#post = current_user.posts.build(post_params)
#post.save
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:user_id, :content, :avatar)
end
end
Lastly my homepage index
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-5">
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= render 'posts/form' %>
<% #posts.each do |post|%>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<%= image_tag post.user.avatar.url(:post_pic), class:"img-thumbnail" %>
<%= post.user.name %>
</h3>
</div>
<div class="panel-body">
<%= post.content %></br></br>
<% if post.avatar.file? %>
<%= image_tag post.avatar.url(:test), class:"img-thumbnail" %></br>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
Routes
Rails.application.routes.draw do
resources :posts
get 'users/index'
get 'users/show'
root 'home#index'
devise_for :users
So, you're doing like saving post data using another Controller(Home) instead of Post Controller, right?
Your partial form for post uses:
<%= form_for(#post) do |f| %>
// #post generated url (/posts)
// will look for create method in POST Controller
I suggest to put your saving codes in proper controller(posts), so you will prevent code duplication/redundancy.
TIP:
If you are worrying about redirection from Home view or from Posts view,
you can use params[:controller] for checking where the request came from, by just using if statement.
Finally, you can redirect it to proper page after saving.

Search on Ruby On Rails 4 [Help]

Newbie on RoR. I want to search division, category and brand (by name, not by id). I have a problem to figure out a search function. Hopefully I can get out from my problem. What should I do to convert (division_id) --> (division_name), etc?
**#Model**
item.rb :
belongs_to :division
belongs_to :category
belongs_to :brand
def self.search(params)
items = Item.all
items = items.where("division_id BETWEEN #{params[:division_from].to_i} AND #{params[:division_to].to_i}") if params[:division_from].present?
items = items.where("category_id BETWEEN #{params[:category_from].to_i} AND #{params[:category_to].to_i}") if params[:category_from].present?
items = items.where("brand_id BETWEEN #{params[:brand_from].to_i} AND #{params[:brand_to].to_i}") if params[:brand_from].present?
end
category.rb :
has_many = items
division.rb :
has_many = items
brand.rb :
has_many = items
**#View**
items- index.html.erb
<fieldset><legend>Filter</legend></fieldset>
<div class="panel-body">
<div class="row">
<%= form_tag search_items_path, class: "form-horizontal bucket-form", remote: true do %>
<div class="col-md-6">
<div class="form-group">
<div class="text-field">
<div class="col-md-10">
<td>Division</td>
<div class="input-group input-large">
<%= text_field_tag 'division_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'division_to','', class: "form-control dpd1" %>
</div>
<td>Category</td>
<div class="input-group input-large">
<%= text_field_tag 'category_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'category_to','', class: "form-control dpd1" %>
</div>
<td>Brand</td>
<div class="input-group input-large">
<%= text_field_tag 'brand_from','', class: "form-control dpd1" %>
<span class="input-group-addon">To</span>
<%= text_field_tag 'brand_to','', class: "form-control dpd1" %>
</div>
<div class="btn-group">
<%= submit_tag 'Search', class: "btn btn-primary" %>
</div>
</div>
</div>
</div>
</div>
<% end %>
</div>
</div>
**#Controller**
items_controller.rb :
def search
#items = Item.search(params)
respond_to do |format|
format.js
end
end
If I execute my code, I have search by id (not by name).. Thanks before
Well.. first, if you want to search only one division-category-brand, change the view for every item only one text input (but its better to use select/multiselect).
Using text input:
only one text input per class
e.g. <%= text_field_tag 'brand','', class: "form-control dpd1" %>
in the item.rb change the search method to this
def self.search(params)
items = Item.all
items = items.where(division_id:Division.find_by_name(params[:division])) if params[:division].present?
items = items.where(category_id:Category.find_by_name(params[:category])) if params[:category].present? items = items.where(brand_id:Brand.find_by_name(params[:brand])) if params[:division].present?
end
It will not work when you're not filling the correct name in the view, so i suggest to use select/multiselect.
I hope it will work.

simple_form inline on rails 4

I am using a simple_form and bootstrap in rails 4. I want the start date and start time to be on the same line and end date and end time on the same line. I have tried the solutions from similar problems but none of them are working. I am a newbie in rails. Please help me.
Here is my code:
<%= b.input :start_date, wrapper: :horizontal_input_group do %>
<%= b.input_field :start_date, class: "form-control date start" %>
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
<% end %>
<%= b.input :start_time, wrapper: :horizontal_input_group do %>
<%= b.input_field :start_time, as: :string, class: "form-control time start" %>
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
<% end %>
<%= b.input :end_date, wrapper: :horizontal_input_group do %>
<%= b.input_field :end_date, class: "form-control date end" %>
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
<% end %>
<%= b.input :end_time, wrapper: :horizontal_input_group do %>
<%= b.input_field :end_time, as: :string, class: "form-control time end" %>
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
<% end %>
<% end %>
getbootstrap.com/css/#grid this is what you should read. After wrapping your code with a <div class="container"></div> and inside that a <div class="row"></div> you can use the bootstrap columns to make your way and align everything perfectly.

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.