I have this array:
[:dk, #<Domain dk: 8, id: 12, se: 5, com: 5>]
I want to select the dk: 8?
So that the input is: 8
My view:
<% #prices.each do |price| %>
<%= price %><br />
<% end %>
The output:
[:dk, #<Domain dk: 8, id: 12, se: 5, com: 5>]
[:com, #<Domain dk: 8, id: 12, se: 5, com: 5>]
My controller:
def domain
country_codes = %w[ dk com ]
#domain = "asdsad"
#results = { }
#prices = { }
country_codes.each do |cc|
#results[cc] = Whois.whois("#{#domain}.#{cc}")
#prices[cc.to_sym] = Domain.order(cc).first
end
render :layout => false
end
You don't have an Array, you have a Hash.
Do this:
<% #prices.each do |cc,domain| %>
<%= domain.send(cc) %><br />
<% end %>
So:
first: #<Domain dk: 8, id: 12, se: 5, com: 5>.send(:dk) # => 8
second: #<Domain dk: 8, id: 12, se: 5, com: 5>.send(:com) # => 5
Upon request, further explanation.
you create a Hash: #prices = { }
then you fill it: #prices[cc.to_sym] = Domain.order(cc).first
The latest means to you add to the hash one object: Domain.order(cc).first, with it's key: cc.to_sym
Related
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
I have an array:
<% #widgets.each do |w| %>
...
<% end %>
How can I display them in groups? Let's say by 4:
<div>1, 2, 3, 4</div>
<div>5, 6, 7, 8</div>
etc.
Thank you.
For the specific example you gave, you want each_slice:
<% #widgets.each_slice(4) do |ws| %>
<div><%= ws.join(', ') %></div>
<% end %>
You might also be interested in each_cons (each consecutive, e.g. "1,2,3", "2,3,4", "3,4,5", etc.) or group_by for arbitrary groupings.
Person = Struct.new(:name,:age,:male) do
def inspect
"<#{'fe' unless male}male '#{name}' #{age}>"
end
end
all = [
Person.new("Diane", 12, false),
Person.new("Harold", 28, true),
Person.new("Gavin", 38, true),
Person.new("Judy", 55, false),
Person.new("Dirk", 59, true)
]
p all.group_by(&:male)
#=> {
#=> false=>[ <female 'Diane' 12>, <female 'Judy' 55> ],
#=> true =>[ <male 'Gavin' 38>, <male 'Harold' 28>, <male 'Dirk' 59> ]
#=> }
p all.group_by{ |person| (person.age / 10) * 10 }
#=> {10=>[<female 'Diane' 12>],
#=> 20=>[<male 'Harold' 28>],
#=> 30=>[<male 'Gavin' 38>],
#=> 50=>[<female 'Judy' 55>, <male 'Dirk' 59>]}
Try to use each_slice(n):
require 'erb'
#widgets = (1..8).to_a
template = <<EOF
<% #widgets.each_slice(4) do |w| %>
<div><%= w.join(', ') %></div>
<% end %>
EOF
puts ERB.new(template).result(binding)
# =>
<div>1, 2, 3, 4</div>
<div>5, 6, 7, 8</div>
In a Rails 3.1 app, I have a controller returning a set of objects (children) in an index view using this code:
def index
#children = Child.all
#base_class = "children-index"
#title = "Your Children"
respond_to do |format|
format.html # children/index.html.erb
format.json { render :json => #children }
end
end
The index.html.erb view is written like so:
<h1><%= title %></h1>
<ul>
<%= #children.each do |child| %>
<li><%= link_to child.fullname, child_path(child) %></li>
<% end %>
</ul>
For some reason, the JSON response is getting thrown into the HTML response and I cannot determine the reason. None of my other index views are having this issue and their code is very close to the same.
John Jake Smith Jr
Jane Ann Doe
[#<Child id: 1, firstname: "John", middlename: "Jake", lastname: "Smith", suffix: "Jr", gender: "Male", dob_actual: "2011-01-05", dob_expected: "2011-01-01", height: 30, weight: 40, created_at: "2011-10-28 21:32:54", updated_at: "2011-10-28 21:32:54">, #<Child id: 2, firstname: "Jane", middlename: "Ann", lastname: "Doe", suffix: "", gender: "Female", dob_actual: "2011-05-05", dob_expected: "2011-05-01", height: 30, weight: 12, created_at: "2011-11-07 18:08:54", updated_at: "2011-11-07 18:08:54">]
That's not JSON, that's inspect output. You're getting that because each returns #children and you're using <%= here:
<%= #children.each do |child| %>
You want just this:
<% #children.each do |child| %>
Did you forget to do #children.to_json in your controller?
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
I'm getting up to speed on rails and ran into an odd problem. I'm rendering some images from the database (Image models attached to another model, Plants). I'm having some trouble when attempting to do it via a partial. I've got show.html.erb
<fieldset class="fieldset">
<legend>Images</legend>
<%= unless #plant.images.blank? then
for image in #plant.images
debugger
render :partial => 'show_image', :object => image
end
else
"This plant has no images to display."
end
%>
</fieldset>
And the partial _show_image.html.erb:
<div class="image_container">
<% debugger %>
<img src="<%= url_for(:action => 'picture', :id => object.id) %>"/>
<p class='image_caption'><%= object.comment %></p>
</div>
When this is rendered it just renders a "#" for each image, rather than the actual image. It seems to be just rendering the object as a string, as in the source I get:
<fieldset class="fieldset">
<legend>Images</legend>
#<Image:0x242c910>
</fieldset>
When running through the debugger locally:
/Users/*****/dev/plantmanager/app/views/plants/show.html.erb:54
debugger
(rdb:241) image
#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil>
(rdb:221) #plant
#<Plant id: 55, name: "Test", description: "Test", created_at: "2009-05-07 07:19:44", updated_at: "2009-05-07 07:19:44", planted: "2009-05-07 00:00:00", sprouted: "2009-05-15 00:00:00", plant_type_id: 1, finished: "2009-05-27 00:00:00">
(rdb:221) #plant.images
[#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil>]
(rdb:221) continue
/Users/*****/dev/plantmanager/app/views/plants/_show_image.html.erb:2
<% debugger %>
(rdb:221) object
#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil>
(rdb:221) object.id
40
(rdb:221) object.comment
"Test"
(rdb:221) continue
Here are my models [snipped a bit]:
class Plant < ActiveRecord::Base
has_many :images
validates_presence_of :name
validates_presence_of :plant_type_id
validates_associated :images
after_update :save_images
def image_attributes=(image_attributes)
image_attributes.each do |attributes|
# TODO: Probably handle validation in the image model?
if attributes[:id].blank?
unless attributes[:uploaded_picture].blank?
tmpImg = images.build()
tmpImg.uploaded_picture=attributes[:uploaded_picture]
tmpImg.comment = attributes[:comment]
end
else
img = images.detect { |i| i.id == attributes[:id].to_i }
img.attributes = attributes
end
end
end
def save_images
images.each do |i|
if i.should_destroy?
i.destroy
else
i.save(false)
end
end
end
end
class Image < ActiveRecord::Base
validates_format_of :content_type,
:with => /^image/,
:message => "--- you can only upload pictures"
attr_accessor :should_destroy
def should_destroy?
should_destroy.to_i == 1
end
def uploaded_picture=(picture_field)
self.name = base_part_of(picture_field.original_filename)
self.content_type = picture_field.content_type.chomp
self.data = picture_field.read
#image = MiniMagick::Image.from_blob self.data
#self.thumbnail = resize_and_crop(image, 100).to_blob
end
def base_part_of(file_name)
File.basename(file_name).gsub(/[^\w._-]/, '')
end
end
Try this instead:
<% unless #plant.images.blank?
for image in #plant.images
%>
<%= render :partial => 'show_image', :object => image %>
<% end
else %>
This plant has no images to display.
<% end %>
Sorry about the formatting, but you get the idea.
Build a method for the pic in your Image model
class Image < ActiveRecord::Base
belongs_to :plant
validates_presence_of :uploaded_picture
...
end
In your plants controller
def plant_pic
img = Image.find(params[:id])
# THE NEXT LINE IS THE ONE I THINK YOU ARE MISSING:
send_data img.uploaded_picture, :filename =>"plant#{img.plant_id}_#{img.id.to_s}+'.jpg',
:type => 'image/jpeg',
:disposition => 'inline'
end
...
And then in your plants view:
<fieldset class="fieldset">
<legend>Images</legend>
<% if plant.images.blank? -%>
<p>This plant has no images to display.</p>
<% else %>
<%= #plant.images.each do |image| %>
<div class="img_container">
<img src="<%= url_for(:action => 'plant_pic', :id => image.id) %>"/>
</div>
<% end -%>
<% end -%>
</fieldset>
You may want to encode/decode the uploaded_picture binary field someway (I use Base64.encode and Base64.decode) in your images controller, but that's another issue.
Hope that helps you