Home > Blockchain >  Rails - how to reference array positions in output
Rails - how to reference array positions in output

Time:12-26

I am trying to output an array in a certain way. Here is the method that gets the data:

def days
    {
      monday:    monday,
      tuesday:   tuesday,
      wednesday: wednesday,
      thursday:  thursday,
      friday:    friday,
      saturday:  saturday,
      sunday:    sunday
    }
end

def to_ice_cube_time
[start_time, end_time, *days.compact_blank.keys]
end  

The output of this is like this:

[["6:00 AM", "8:00 AM", :monday, :tuesday], ["9:00 AM", "6:00 PM", :thursday, :friday], ["8:00 AM", "4:00 PM", :monday, :tuesday]]

I am trying to loop this in the view and output the correct times on the correct days of the week. Struggling to get the individual values though.

<% scheduleevent.to_ice_cube_time.each do |timerange| %>
   <p><%= timerange.start_time %> - <%= timerange.end_time %> </p>
<% end %>

That is how I would like to do it, but I get an error "undefined method `start_time' for [["6:00 AM", "8:00 AM", :monday, :tuesday], ["9:00 AM", "6:00 PM", :thursday, :friday], ["8:00 AM", "4:00 PM", :monday, :tuesday]]:Array"

Any suggestions?

CodePudding user response:

Edit: I would look at making a helper method for displaying the data you want in the format you want like this:

#schedule_events_helper.rb

def time_slots(day)
  Scheduleevent.joins(:schedtimeranges).where(day => true).order(:start_time).pluck(:start_time, :end_time)
end

Then in your view you can do something like:

<% %w(:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday).each do |day|
  <%= day.to_s.titleize %>
  <br>
  <% time_slots(day).each do |slot| %>  
    <%= slot[0] %> - <%= slot[1] %>
    <br>
  <% end %>
<% end %>

This keeps it very obvious what you are doing to get the data and how it is being manipulated to get it to the desired format.

*** older answer below, either should work ***

You are trying to use an ActiveRecord method on an array. Arrays are referenced by their index, which starts at zero moving left to right. You could do:

<% scheduleevent.to_ice_cube_time.each do |timerange| %>
 <p><%= timerange[0] %> - <%= timerange[1] %> </p>
<% end %>

Per your comment that this references a previous answer you should include that link in your question and explain that. I still think you should rework the original query to get the data in the format you want rather than all of these twists and turns. As soon as things are put into an array format you loose a lot of the obvious data meaning. You want a hash output like

{monday: [["6:00 AM", "8:00 AM"], ["8:00 AM", "4:00 PM"]], tuesday: [["4:00 AM", "8:00 AM"], ["6:00 AM", "4:00 PM"]]...}

Given your previous post:

days_of_week = %w(:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday)

output = {}
days_of_week.each do |day|
  output[day] = Scheduleevent.joins(:schedtimeranges).where(day => true).order(:start_time).pluck(:start_time, :end_time)
end

this should give you an output of

{monday: [['6:00 AM', '11:00 AM'], ['8:00 AM', '4:00 PM']...],
 tuesday: [['4:00 AM', '11:00 AM'], ['8:00 AM', '4:00 PM']...],
 ...}

And easily represented as: #note I changed this to a simpler form

  <% output.each do |day,times| %>
     <%= day.to_s.titleize %>
     <br>
     <% times.each do |slot| %>
       <%= slot[0] %> -  <%= slot[1] %>
       <br>
     <% end %>
  <% end %>

Think about how you want the final data structured and try to make the code produce that as simply as possible. There are many other ways to tweak by writing instance methods or helper methods to format the output of the data.

CodePudding user response:

The error that you are getting is because you are trying to access a position of an array as if it where a method.

Either you just print out timerange[0]

or you make your to_ice_cube_time method return a Hash so you can read it like timerage[:start_time]

Or even, you could use the Hashie gem to wrap it and read it like it is.

If you are using the new Ruby syntax it would look like this

def to_ice_cube_time
  Hashie::Mash.new({ start_time:, end_time:, days: *days.compact_blank.keys })
end 
  • Related