Item ordered by category - ruby-on-rails

I have these in my database. Each item is in some category, and I want to display all items in the category ordered along with the category id. Something like this:
1
Expresso
Americano
2
Capuchino
Here is my seed code:
{content: "expresso", price: "29000", category_id: 1},
{content: "Americano", price: "29000", category_id: 1},
{content: "Capuccino", price: "35000", category_id: 2},
This is the controller action that performs the query:
def menu
#items = Item.order('content ASC')
end

In your view:
<%- Category.includes(:items).order('categories.id').each do |category| %>
<%= category.id %>
<%- category.items.each do |item| %>
<% = item.content %>

Related

Replace params data from name to id before save in rails

How to replace item name to item id before save in database.
This is my controller code
def create
#supplier = Supplier.new(supplier_params)
if #supplier.save
item_code = params[:supplier_item][:item_ids]
item_id = Item.where(:item_code => item_code).pluck(:id)
item_params = params.require(:supplier_item).permit(item_ids: [], location_ids:[], supplier_prices: [])
items = item_params[:item_ids].zip(*item_params.values_at(:location_ids, :supplier_prices))
items.map do |item_id, location_id, supplier_price|
supplier_item = SupplierItem.new({
item_id: item_id,
location_id: location_id,
supplier_price: supplier_price,
supplier_id: #supplier.id
})
supplier_item.save
end
flash[:success] = "New supplier created"
redirect_to supplier_path(#supplier)
else
render 'new'
end
end
So this code now save item_ids["Apple", "Banana"]. But I want to save this in id form which is like this item_ids["1", "3"]
This is my view code
<%= f.label :item, class: 'required'%>
<% items = Item.where(company_id: current_user.company.id)%>
<%= text_field_tag "[supplier_item][item_ids][]", nil, {list: 'browser-item'} %>
<% items.each do |item| %>
<option data-value = <%= item.id %> value = <%= "#{item.item_code} - #{item.name}" %>></option>
<% end %>
So I try this to get item id of the item name
Item.where(:item_code => item_name).pluck(:id)
This one give me all the item id I were selected. So how should I replace this id into the params

Filter and map by grouping data

I have an array of objects, where I have the following fields: title, name e url
My data:
#array = [
{ id: 1, title: '123', name: 123 },
{ id: 2, title: '123', name: 321 },
{ id: 3, title: '1234', name: 123 },
]
I need to group my data by title and then make the map with the names
<%= #array.map do |x| %>
<div class='col-md-12'>
<h3><%= x.title %></h3>
<div class="row">
<%= #array.filter do |y| %>
<div class="col-4">
<% if y.title === x.title %>
<p><%= t.name %></p>
<% end %>
</div>
<% end.join.html_safe %>
</div>
</div>
<% end.join.html_safe %>
The return is:
title = '123'
name = '123'
name = '321'
title = '123'
name = '123'
name = '321'
title = '123'
name = '123'
That is, my array comes duplicated ... how to proceed?
Remembering that I am inside the rails view
You're getting duplicate entries since you're mapping over all the elements and filtering the array for every element inside the block.
You can use Enumerable#group_by to group the array elements by title. You can then iterate over the groups and display the title and names of each group. Note that I'm using item[:name] to access the values from the hash since your question mentions an array of hashes. You should update it to item.name (and other places using hash access) if you're working with objects instead.
#groups = #array.group_by {|i| i[:title] }
<% #groups.each do |title, items| %>
<h3><%= title %></h3>
<% items.each do |item| %>
<p><%= item[:name] %></p>
<% end %>
<% end %>

How to show organized data from rails helper content tag

How to show organized data from rails helper content tag?
Like below is my helper method and I want to show all categories name grouped by a parent, and that is ul li if you can please see below method I think you will understand that code & what do I want. That method outputted the data but not with ul li
The helper method
def category
parent_categories = Category.select(:id, :name, :parent).group_by(&:parent)
parent_categories.each do |parent, childs|
content_tag(:div) do
content_tag(:h1, parent)
end +
content_tag(:ul) do
childs.each do |child|
content_tag(:li, child.name)
end
end
end
end
the output of <%= category %>
{"Technology"=>[#<Category id: 1, name: "Programming", parent: "Technology">, #<Category id: 3, name: "Ruby on Rails", parent: "Technology">, #<Category id: 9, name: "Full Time", parent: "Technology">, #<Category id: 14, name: "Business Opportunities", parent: "Technology">, #<Category id: 15, name: "Contract & Freelance", parent: "Technology">, #<Category id: 18, name: "Engineering", parent: "Technology">, #<Category id: 25, name: "IT", parent: "Technology">],
"Education"=>[#<Category id: 5, name: "Industry", parent: "Education">, #<Category id: 6, name: "Education", parent: "Education">, #<Category id: 7, name: "Education & Industry", parent: "Education">, #<Category id: 16, name: "Customer Service", parent: "Education">, #<Category id: 17, name: "Diversity Opportunities", parent: "Education">],
"Other"=>[#<Category id: 8, name: "Part Time", parent: "Other">, #<Category id: 12, name: "Admin & Clerical", parent: "Other">]}
the schema.rb
create_table "categories", force: :cascade do |t|
t.string "name"
t.string "parent"
end
That was my done works.
After the example is what do I want like
Technology (Parent)
Programming
Ruby on Rails
Ruby
ReactJS
Education (Parent)
Office
Teacher
Physics
Other (Parent)
Clinical
Helth
etc...
Please help out me to done this works.
Thanks
You are using ERB in your helper but it is not an html.erb file so you don't get the tags you are trying to create. Why not just use the hash you've produced and then I think what you are looking for is something like:
The helper method:
def category
Category.select(:id, :name, :parent).group_by(&:parent)
end
And in your view file (.html.erb) do something like:
<% category.each do |cat, list| %>
<div class="category">
<b> <%= cat %> </b>
<ul>
<% list.each do |item| %>
<li> <%= item.name %> </li>
<% end %>
</ul>
</div>
<br>
<% end %>
OK, you can do it the way you are proposing using the concat method according to the documentation:
def category
parent_categories = Category.select(:id, :name, :parent).group_by(&:parent)
parent_categories.each do |parent, childs|
concat content_tag(:div) do
concat content_tag(:h1, parent)
end
concat content_tag(:ul) do
childs.each do |child|
concat content_tag(:li, child.name)
end
end
end
end

Show categories/sub-categories in tree hierarchy inside a dropdown

I have a category table with fields id,name and parent_id. The root categories have parent_id 0. Now i want to show the list of categories in a drop down and a structure like this:
root_category
first_sub_category
sub_sub_category
another_sub_sub_category
second_sub_category
another_root_category
first_sub_category
second_sub_category
Here's my Controller:
def new
#category = Category.new
end
And here's the view:
<%= f.label :parent_category %>
<% categories = Category.all.map{|x| [x.name] + [x.id]} %>
<%= f.select(:parent_id, options_for_select(categories), {}, class: 'form-control') %>
Please Help.
Assuming you can get the children of a given category similar to:
has_many :children, :class_name => 'Category', :foreign_key => 'parent_id'
Create a method for categories to get all children and indent each by the level:
def all_children2(level=0)
children_array = []
level +=1
#must use "all" otherwise ActiveRecord returns a relationship, not the array itself
self.children.all.each do |child|
children_array << " " * level + category.name
children_array << child.all_children2(level)
end
#must flatten otherwise we get an array of arrays. Note last action is returned by default
children_array = children_array.flatten
end
Then in your view:
<select>
<option></option>
<% root_categories.each do |category| %>
<option><%=category.name%></option>
<% category.all_children2.each do |child| %>
<option><%=child.html_safe%></option>
<% end %>
<% end %>
</select>
I haven't 100% tested this but the bits I did suggest it should work...
Solved the problem by adding these functions in application_helper.rb
def subcat_prefix(depth)
(" " * 4 * depth).html_safe
end
def category_options_array(current_id = 0,categories=[], parent_id=0, depth=0)
Category.where('parent_id = ? AND id != ?', parent_id, current_id ).order(:id).each do |category|
categories << [subcat_prefix(depth) + category.name, category.id]
category_options_array(current_id,categories, category.id, depth+1)
end
categories
end
and using them in my view like this
<%= f.select(:parent_id, options_for_select(category_options_array), {}, class: 'form-control') %>

Accesing hash keys and attributes from the view

in an attempt to create a model with an array as an atribute, i ended up creating an array of hashes like so:
data1 = {}
data1[:name] = "Virtual Memory"
data1[:data] = #jobs.total_virtual_memory
data2 = {}
data2[:name] = "Memory"
data2[:data] = #jobs.total_memory
#data = []
#data << data1
#data << data2
which populates #data like this:
[{:data=>[#<Job day: "2010-08-02">, #<Job day: "2010-08-04">], :name=>"Virtual Memory"}, {:data=>[#<Job day: "2010-08-02">, #<Job day: "2010-08-04">], :name=>"Memory"}]
However i do not know how to acces these variables in the view. So as tu run somethig like:
for series in #data
series:name
for d in series:data
data:[Date, Value]
end
end
which would return something along the lines of:
Name1
Date1, Value1
Date2, Value 2,
Date3, Value 3,
Date4, Value 4,
Name2
Date1, Value 1,
Date2, Value 2,
Date3, Value 3,
Date4, Value 4,
This should work:
<% for series in #data %>
<%= series[:name] %>
<% for d in series[:data] %>
<%= d.date %>, <%= d.value %>
<% end %>
<% end %>
However you might consider using a more suitable datastructure instead of hashs. A Struct for example. This could look like this:
# in lib/JobData.rb:
JobData = Struct.new(:name, :data)
# in the controller:
data1 = JobData.new("Virtual Memory", #jobs.total_virtual_memory)
data2 = JobData.new("Memory", #jobs.total_memory)
#data = [data1, data2]
# in the view:
<% for series in #data %>
<%= series.name %>
<% for d in series.data %>
<%= d.date %>, <%= d.value %>
<% end %>
<% end %>
As a style point: I used for because you used for, but in general it's considered more rubyish to use each instead.
Here is the view:
<% for d in #data %>
{ pointInterval: <%= 1.day * 1000 %>,
name:<%= "'#{d[:name]}'"%>,
pointStart: <%= 2.weeks.ago.at_midnight.to_i * 1000 %>,
data: [
<% for chart in d[:data] %>
<%= "'[#{chart.day.to_time(:utc).to_i * 1000}, #{chart.data_attribute}],'" %>
<% end %>
]
},
<% end %>
Use #{d[:name]} to access the value of the "name" key and use d[:data] to access the array, then just loop throughthe array as if it were any normal array

Resources