Search code examples
rubyruby-on-rails-4sequel

Why is it showing identical data at each iteration of .each


I have tried making the data according to @wifis (based on mac_id) is generated but currently the data is identical with the following code -

Controller:

class DashboardsController < ApplicationController
  before_action :authenticate_user!
  def show
    @wifis = Wifi.where(user_id: current_user.id)
    pdaily_number_of_logins_data = []
    phourly_total_traffic_data = []
    pper_user_monthly_traffic_data = []
    @wifis.each do |wifi|
      daily_number_of_logins_data = Radacct.fetch("SELECT gd_day(acctstarttime, 'UTC') AS date, COUNT(*) AS count FROM radacct WHERE (`calledstationid` = ?) AND (`acctstarttime` >= ?) GROUP BY date", wifi.mac_id, 1.month.ago)
      pdaily_number_of_logins_data += daily_number_of_logins_data.to_a if daily_number_of_logins_data.to_a
      @daily_number_of_logins = pdaily_number_of_logins_data.collect{|i| [i[:date],i[:count]]}
      hourly_total_traffic_data = Radacct.fetch("SELECT gd_hour_of_day(acctstarttime, 'UTC') AS hour_of_day, ROUND(((SUM(acctinputoctets)+SUM(acctoutputoctets))/1049000)) AS totaltraffic FROM radacct WHERE (`calledstationid` = ?) AND (`acctstarttime` >= ?) GROUP BY hour_of_day", wifi.mac_id, 1.day.ago)
      phourly_total_traffic_data += hourly_total_traffic_data.to_a if hourly_total_traffic_data.to_a
      @hourly_total_traffic = phourly_total_traffic_data.collect{|i| [i[:hour_of_day],i[:totaltraffic]]}
      per_user_monthly_traffic_data = Radacct.fetch("SELECT username, ROUND(((SUM(acctinputoctets)+SUM(acctoutputoctets))/1049000)) AS `traffic` FROM `radacct` WHERE (`calledstationid` = ?) AND (`acctstarttime` >= ?) GROUP BY username", wifi.mac_id, 1.month.ago)
      pper_user_monthly_traffic_data += per_user_monthly_traffic_data.to_a if per_user_monthly_traffic_data.to_a
      @per_user_monthly_traffic = pper_user_monthly_traffic_data.collect{|i| [i[:username],i[:traffic]]}
    end
  end
end

and View:

% @wifis.each do |wifi| %>
  <h1><%= wifi.mac_id %></h1>
  <%= line_chart @daily_number_of_logins, { discrete: true, library: {hAxis: {title: "Date"}, vAxis: {title: "Number of Logins (daily)"}}} %>
  <%= column_chart @hourly_total_traffic, {library: {hAxis: {title: "Hour"}, vAxis: {title: "Traffic in Megabytes (hourly)"}}} %>
  <%= pie_chart @per_user_monthly_traffic, discrete: true %>
<% end %>

i have tried the above based on this answer but the problem that i am having is @wifi object is used in both controller and views: Loop within Loop in Rails Controller


Solution

  • The problem is that loop in your controller action runs and overwrites the instance variables on each iteration. So only the last iteration remains. If you wanted to save data for each wifi, you need another data structure, not plain ivars. Perhaps a hash where wifi is the key.

    @counters = {}
    @wifis.each do |wifi|
      @counters[wifi] ||= {}
      @counters[wifi][:daily_number_of_logins] = ...
    

    Then in the view

      <% @wifis.each do |wifi| %>
        <%= line_chart @counters[wifi][:daily_number_of_logins] %>
      <% end %>