Instance Variable loop inside the controller - ruby-on-rails

I have some repeated code inside one of my controllers that I would like to consolidate into a loop, but I can't find any clear instruction on how to do so since this seems to be a unique use case for gmaps4rails. I tried creating an array of instance variables but it didn't seem to work! The code I'd like to consolidate:
stores_controller.rb -->
class StoresController < ApplicationController
def map
#rep1 = Store.where(:user_id => "1")
#rep2 = Store.where(:user_id => "10")
#rep3 = Store.where(:user_id => "11")
#rep4 = Store.where(:user_id => "12")
#rep5 = Store.where(:user_id => "13")
#rep6 = Store.where(:user_id => "14")
#rep7 = Store.where(:user_id => "15")
#rep8 = Store.where(:user_id => "16")
#rep9 = Store.where(:user_id => "17")
#repA = Store.where(:user_id => "18")
#hash1 = Gmaps4rails.build_markers(#rep1) do |store, marker|
marker.lat store.lat
marker.lng store.long
marker.title store.name
marker.infowindow "#{store.store_infowindow}"
marker.picture({
:url => "//chart.apis.google.com/chart?chst=d_map_pin_letter&chld=TP|81DF08|000000",
:width => 52,
:height => 32
})
end
#hash2 = Gmaps4rails.build_markers(#rep2) do |store, marker|
marker.lat store.lat
marker.lng store.long
marker.title store.name
marker.infowindow "#{store.store_infowindow}"
marker.picture({
:url => "//chart.apis.google.com/chart?chst=d_map_pin_letter&chld=BS|267AD2|D9E1FF",
:width => 52,
:height => 32
})
end
#hash3 = etc, etc, etc...
I'll also include the marker loader from my map JS in the view file for good measure,
map.html.erb -->
markers = handler.addMarkers(<%=raw #hash1.to_json %>), handler.addMarkers(<%=raw #hash2.to_json %>),
handler.addMarkers(<%=raw #hash3.to_json %>), handler.addMarkers(<%=raw #hash3.to_json %>),
handler.addMarkers(<%=raw #hash4.to_json %>), handler.addMarkers(<%=raw #hash5.to_json %>),
handler.addMarkers(<%=raw #hash6.to_json %>), handler.addMarkers(<%=raw #hash7.to_json %>),
handler.addMarkers(<%=raw #hash8.to_json %>), handler.addMarkers(<%=raw #hash9.to_json %>),
handler.addMarkers(<%=raw #hashA.to_json %>);
The gmaps4rails marker building #hash variables continue their individual loops through all 10 reps beyond these first two indicated here. The only two variables within these hashes are the 'build_markers(#rep#)' call and the 'chld=TP|81DF08|000000' call which indicates the initials and color of the marker for each user. I'm a beginner, so for all I know I could be doing this completely wrong from the start! Any advice is appreciated. Thanks!
EDIT -->
My consolidated code, which ended up being as simple as adding a "Marker" column to my user table since that was the only hard-coded variable that needed changing, in the form of '#{store.user.marker}' within the map marker URL:
stores_controller.rb -->
def map
#stores = Store.all
#hash = Gmaps4rails.build_markers(#stores) do |store, marker|
marker.lat store.lat
marker.lng store.long
marker.title store.name
marker.infowindow "#{store.store_infowindow}"
marker.picture({
:url => "//chart.apis.google.com/chart?chst=d_map_pin_letter&chld=#{store.user.marker}",
:width => 52, :height => 32
})
end
respond_to do |format|
format.html
format.json { render json: #hash }
end
end

A better way to do this is to simply fetch the records from the db and store the whole collection in one instance variable.
#stores = Store.where(user_id: [1, 2, 3])
#markers = Gmaps4rails.build_markers(#stores) do |store, marker|
marker.lat store.lat
marker.lng store.long
marker.title store.name
marker.infowindow "#{store.store_infowindow}"
# if they need different pictures handle it in the model
marker.picture({
:url => "//chart.apis.google.com/chart?chst=d_map_pin_letter&chld=TP|81DF08|000000",
:width => 52,
:height => 32
})
end
Doing this:
#rep1 = Store.where(:user_id => "1")
#rep2 = Store.where(:user_id => "10")
#rep3 = Store.where(:user_id => "11")
#rep4 = Store.where(:user_id => "12")
#rep5 = Store.where(:user_id => "13")
#rep6 = Store.where(:user_id => "14")
#rep7 = Store.where(:user_id => "15")
Is horrible for performance since each line will create a separate database query. If you are new at ruby I would suggest doing something like http://tryruby.org and learning how to manipulate arrays and hashes and the basics before trying to solve more complex problems.

Related

Gmaps4rails marker depending on current user

Is there a way to view markers using gmaps4rails gem, depending on the current user login? I'm not sure if there was any chance it might have worked out, but I tried using the cancan gem in combination but it only results in all of the markers disappearing. Unfortunately I have no other idea how to carry on. So what I am trying to achieve is to make markers visible depending on which user is currently logged in. I am grateful for any help!
Current code of relations_controller:
def index
#relations = Relation.all
#hash1 = Gmaps4rails.build_markers(#relations) do |relation, marker|
# something like "if current_user == relation.user_id" ?
marker.lat relation.childlat
marker.lng relation.childlng
marker.picture({
:url => ActionController::Base.helpers.image_path("childgross.png"),
:width => "45",
:height => "45"
})
end
#hash2 = Gmaps4rails.build_markers(#relations) do |relation, marker|
marker.lat relation.kigalat
marker.lng relation.kigalng
marker.picture({
:url => ActionController::Base.helpers.image_path("persongross.png"),
:width => "45",
:height => "45"
})
end
end
code in relations index view:
<%=raw #hash1.to_json %>
<%=raw #hash2.to_json %>
<script>
handler = Gmaps.build('Google');
handler.buildMap({provider: {},internal: {id: 'map'}},function(){
markers = handler.addMarkers(<%=raw #hash1.to_json %>);
markers = handler.addMarkers(<%=raw #hash2.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
Thnaks to #Pablo It just came to me... I just had to replace #relations = Relation.all with #relations = Relation.where(user_id: current_user.id)

Rails gem axlsx gem multiple sheet

Is it possible to export in xlsx with multiple sheet using gem axlsx. If not please suggest me the other ways.
I want to export the values of #search, #searchg, #clients, #overtimes in different sheets.
#search = Operation.where(:date => params[:from_date].to_datetime..(params[:to_date].to_datetime + 1.day))
#searchg = Guard.where(:status => true).where(:induction_date => params[:from_date].to_datetime..(params[:to_date].to_datetime + 1.day))
#searcht = Guard.where(:status => false).where(:terminate_date => params[:from_date].to_datetime..(params[:to_date].to_datetime + 1.day))
#clients = Client.where(:status => false).where(:terminate_date => params[:from_date].to_datetime..(params[:to_date].to_datetime + 1.day))
#overtimes = Overtime.where(:date => params[:from_date].to_datetime..(params[:to_date].to_datetime + 1.day))
respond_to do |format|
format.js
format.xlsx {render xlsx: 'report', filename: "Operation_reports_#{params[:from_date]}_#{params[:to_date]}.xlsx"}
end
Yep, axlsx supports multiple sheets. In fact, you can see it in the very first code snippet in its readme:
Axlsx::Package.new do |p|
p.workbook.add_worksheet(:name => "Pie Chart") do |sheet|
sheet.add_row ["Simple Pie Chart"]
%w(first second third).each { |label| sheet.add_row [label, rand(24)+1] }
sheet.add_chart(Axlsx::Pie3DChart, :start_at => [0,5], :end_at => [10, 20], :title => "example 3: Pie Chart") do |chart|
chart.add_series :data => sheet["B2:B4"], :labels => sheet["A2:A4"], :colors => ['FF0000', '00FF00', '0000FF']
end
end
p.serialize('simple.xlsx')
end

Can't get custom icons working on gmaps4rails

#hash = Gmaps4rails.build_markers(#additional_infos) do |additional_info, marker|
marker.lat additional_info.latitude
marker.lng additional_info.longitude
marker.picture({
"picture" => view_context.image_path('/qr-code-icon.png'),
"width" => 32,
"height" => 37
})
end
This is in my index action of controller. The map shows fine with regular markers but I cant seem to get the custom markers to show. I've tried numerous types of different URLs and ways to link to the icons but no luck.
I've tried "url" = > #{root_url} , http localhost etc..
Pulling my hair out
You must use "url" hash key instead of "picture"
#hash = Gmaps4rails.build_markers(#additional_infos) do |additional_info, marker|
marker.lat additional_info.latitude
marker.lng additional_info.longitude
marker.picture({
"url" => view_context.image_path('/qr-code-icon.png'),
"width" => 32,
"height" => 37
})
end
try this, that work for me.
#hash = Gmaps4rails.build_markers(#members) do |member, marker|
marker.lat member.latitude
marker.lng member.longitude
marker.infowindow member.name
marker.picture({
:url => view_context.image_path('marker.png'),
:width => 32,
:height => 37
})

Add marker to center location with gmaps4rails

I have an application where I'm showing a business listing and then displaying various jobs related to that business. The job locations are working great but I'd like to add a marker for the business which should be in the center which I can then customise.
Here is my controller/business_controller
def show
#business = Business.find(params[:id])
#distance = #business.service_area
#jobs = Job.near(#business.location, #distance, {:order => :distance, :units => :km})
#json = #jobs.to_gmaps4rails
#mapoptions = {
"map_options" => {"center_latitude" => #business.latitude,
"center_longitude" => #business.longitude,
"auto_zoom" => true}
}
respond_to do |format|
format.html
end
end
In my view views/businesses/show
<p><%= gmaps(:map_options => #mapoptions,"markers" => { "data" => #json }) %></p>
How can I create a marker for the business location?
I'd say:
markers_array = JSON.parse #jobs.to_gmaps4rails
markers_array << {lat: #business.latitude, lng: #business.longitude}
#json = markers_array.to_json

Place a link within a infowindow using gmaps4rails

I am using gmaps4rails and now when I click on a marker appears information from the database, I need a putting a link inside the marker. How do I?
Model:
def gmaps4rails_address
city
end
def gmaps4rails_infowindow
"<h4>#{city}</h4>"
end
Controller:
def index
#postos = Posto.all
#markers = Posto.all.to_gmaps4rails
#json = Posto.all.to_gmaps4rails do |posto, marker|
marker.json "\"id\": #{posto.id}"
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #postos }
end
end
I don't recommend you use the gmaps4rails_infowindow method: view details shouldn't be given at the model layer.
You should rather configure the infowindow in the controller, using a partial:
#json = Posto.all.to_gmaps4rails do |posto, marker|
marker.infowindow render_to_string(:partial => "/path_to/your_template", :locals => { needed_locales })
end
Details are in the gem's wiki. (you could even use js templates but it's not the question and it's explained in the wiki as well)
Here are two ways.
Directly in the controller:
hashes = Gmaps4rails.build_markers(collection) do |item, marker|
marker.infowindow(ActionController::Base.helpers.link_to(item.name ||= 'Name?',preplan_path(item)).html_safe)
marker.title item.name
marker.picture({
# :url => "/assets/building_icon.png",
:url => "/assets/text.png",
:width => 32,
:height => 32
})
marker.lat item.latitude
marker.lng item.longitude
end
And using a partial from the controller:
hashes = Gmaps4rails.build_markers(collection) do |item, marker|
marker.infowindow render_to_string(:partial => "/structures/info_window", :locals => { :structure => item})
And the partial can be whatever you like:
# view/structures/_info_window.html.haml
= link_to structure.name, [structure.preplan, structure]
- unless structure.longitude.nil?
%br
= link_to "Drive to?", "https://maps.google.com/maps?daddr=#{structure.latitude},#{structure.longitude}", target: "_blank"

Resources