loop not work in haml, but work in html.erb - ruby-on-rails

It's very annoying,
Show nothing
- calendar #date do |date|
= date.day
But output of haml is in my expectation
<%= calendar #date do |date| %>
<%= date.day %>
<% end %>
This is my helper source code.
module CalendarHelper
require 'pry'
def widget
concat link_to("Hello", '')
concat " "
concat link_to("Bye", '')
end
def calendar(date = Date.today, &block)
cal_tbl = Calendar.new(self, date, block).table
# content_tag :div do
# cal_tbl
# end
# return cal_tbl
end
class Calendar < Struct.new(:view, :date, :callback)
HEADER = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
START_DAY = :sunday
delegate :content_tag, to: :view
def table
content_tag :table, class: "calendar" do
header + week_rows
end
end
def header
content_tag :tr do
HEADER.map { |day| content_tag :th, day }.join.html_safe
end
end
def week_rows
weeks.map do |week|
content_tag :tr do
week.map { |day| day_cell(day) }.join.html_safe
end
end.join.html_safe
end
def day_cell(day)
content_tag :td, view.capture(day, &callback), class: day_classes(day)
end
def day_classes(day)
classes = []
classes << "today" if day == Date.today
classes << "notmonth" if day.month != date.month
classes.empty? ? nil : classes.join(" ")
end
def weeks
first = date.beginning_of_month.beginning_of_week(START_DAY)
last = date.end_of_month.end_of_week(START_DAY)
(first..last).to_a.in_groups_of(7)
end
end
end

As per the haml Git,
A hyphen(-), will run the code but not output the result
An equals sign(=), will output the result of the code
so it should be
= calendar #date do |date|
= date.day

Do this:
- calendar #date do |date|
= date.day
Well HAML to HTML translation follows this convention. the rails code that is supposed to be running and not shown is started with a - character, it is equivalent to <% rails code%> in HTML
= in HAML is equivalent of HTML <%= rails code %>, the closing <%end%> is auto generated in response to do rails code.

do this
= calendar #date do |date|
= date.day

Related

undefined method when trying to get the first day of the week - Rails 5

I'm making a calendar, I'm trying to get the first day of the week, as well as the last day of the week. When trying to do this, I get an error in /lib/calencar.rb:
undefined method `beginning_of_month 'for {: date => Wed, 23 Jan 2019}: Hash
This is the code calendar.rb
class Calendar < Struct.new(:view, :date, :callback)
HEADER = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
START_DAY = :sunday
delegate :content_tag, to: :view
def table
content_tag :table, class: "calendar table table-bordered table-striped" do
header + week_rows
end
end
def header
content_tag :tr do
HEADER.map { |day| content_tag :th, day }.join.html_safe
end
end
def week_rows
weeks.map do |week|
content_tag :tr do
week.map { |day| day_cell(day) }.join.html_safe
end
end.join.html_safe
end
def day_cell(day)
content_tag :td, view.capture(day, &callback), class: day_classes(day)
end
def day_classes(day)
classes = []
classes << "today" if day == Date.today
classes << "not-month" if day.month != date.month
classes.empty? ? nil : classes.join(" ")
end
def weeks
#first = DateTime.strptime(date, "%B %d, %Y")
first = date.beginning_of_month.beginning_of_week(START_DAY)
last = date.end_of_month.end_of_week(START_DAY)
(first..last).to_a.in_groups_of(7)
end
end
Also, in the index#index controller I have the following code:
class IndexController < ApplicationController
helper CalendarHelper
def index
#date = params[:date] ? Date.parse(params[:date]) : Date.today
end
end
Thank you
undefined method `beginning_of_month 'for {: date => Wed, 23 Jan 2019}: Hash
You are trying to use a beginning_of_month method on a Hash not on a DateTime object, check the assignment of your date variable.

a Struck constant won't allow me to create a calendar

I am trying to create a calendar and have been following a tutorial on YouTube calendar ruby on rails first video. once I inputted the code I had an error,
uninitialized constant CalenderHelper::Struck
the code is;
module CalenderHelper
def calender(date = Date.today, &block)
Calender.new(self, date, block).table
end
**class Calender < Struck.new(:view, :date, :callback)**
HEADER = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
START_DAY = :sunday
delegate :content_tag, to: :view
def table
content_tag :table, class: "calender" do
header + week_rows
end
end
def header
content_tag :tr do
HEADER.map { |day| content_tag :th, day }.join.html_safe
end
end
def week_rows
week.map do |week|
content_tag :tr do
week.map { |day| day_cell(day) }.join.html_safe
end
end.join.html_safe
end
def day_cell(day)
content_tag :td, view.capture(day, &callback), class: day_classes(day)
end
def day_classes(day)
classes = []
classes << "today" if day == Date.today
classes << "notmonth" if day.month != date.month
classes.empty? ? nil : classes.join(" ")
end
def weeks
first = date.beginning_of_month.beginning_of_week(START_DAY)
last = date.end_of_month.end_of_week(START_DAY)
(first..last).to_a.in_groups_of(7)
end
end
end
line with the error is marker with starts on each side
You have a small spelling mistake:
You want to call the Struct class, not Struck.
your line should be:
class Calendar < Struct.new(:view, :date, :callback)
# the rest of the code
end
Hope that helps

Compare an array of dates to one day (in a rails calendar)

I'm using the calendar helper from Railscast: http://railscasts.com/episodes/213-calendars-revised but I'm running into a problem (calendar helper below):
module CalendarHelper
def calendar(date = Date.today, &block)
Calendar.new(self, date, start_date, end_date, scheduled, block).table
end
class Calendar < Struct.new(:view, :date, :start_date, :end_date, :scheduled, :callback)
HEADER = %w[S M T W T F S]
START_DAY = :sunday
delegate :content_tag, to: :view
def table
content_tag :table, class: "calendar" do
header + week_rows
end
end
def header
content_tag :tr do
HEADER.map { |day| content_tag :th, day }.join.html_safe
end
end
def week_rows
weeks.map do |week|
content_tag :tr do
week.map { |day| day_cell(day) }.join.html_safe
end
end.join.html_safe
end
def day_cell(day)
content_tag :td, view.capture(day, &callback), class: day_classes(day)
end
def day_classes(day)
classes = []
classes << "today" if day == Date.today
classes << "start_date" if day == start_date
classes << "end_date" if day == end_date
classes << "notmonth" if day.month != date.month
classes << "scheduled" if day == scheduled
classes.empty? ? nil : classes.join(" ")
end
def weeks
first = date.beginning_of_month.beginning_of_week(START_DAY)
last = date.end_of_month.end_of_week(START_DAY)
(first..last).to_a.in_groups_of(7)
end
end
end
My application spits out an array of scheduled dates (using the ice_cube gem). For each one of those dates I want to match them with dates from the calendar, assigning them with the class "scheduled". I can't figure out how to do this. This code is what I'm trying to make work:
classes << "scheduled" if day == scheduled
'scheduled' comes from the controller:
Application_Controller.rb
def scheduled
Schedule.find(params[:id]).itinerary.all_occurrences if params[:id]
end
helper_method :scheduled
Which returns the following array of dates:
=> [2014-05-16 00:00:00 -0400, 2014-05-19 00:00:00 -0400, 2014-05-20 00:00:00 -0400, 2014-05-21 00:00:00 -0400, 2014-05-22 00:00:00 -0400, 2014-05-23 00:00:00 -0400, 2014-05-26 00:00:00 -0400, 2014-05-27 00:00:00 -0400, 2014-05-28 00:00:00 -0400, 2014-05-29 00:00:00 -0400]
I've tried a number of scenarios but I can't figure it out.
As an example, this will work and show the "scheduled" class for these 3 days but I can't figure out how to loop through all the scheduled dates and still have an || operator in the block:
def day_classes(day)
...
classes << "scheduled" if Date.yesterday == day || Date.tomorrow == day || Date.today == day
...
end
Or maybe someone has a better idea?
After a bit of reading through the ice_cube gem I found a handy method that does exactly what I needed.
def day_classes(day)
...
classes << "scheduled" if scheduled.itinerary.occurs_on?(day)
...
end

How to present list of names in Presenter?

I have my custom presenter
class ShiftPresenter
def initialize(shift, template)
#shift = shift
#template = template
end
def h
#template
end
def users_list
logs = ShiftLog.by_shift(#shift)
names = logs.map do |log|
log.cardiologist.name
end
h.content_tag :div, names unless names.empty?
end
end
and #index view
- present shift do |shift_presenter|
= shift_presenter.user_list
How to present users names using li instead of ['tom', 'jerry']
You can add this to your presenter method:
def users_list
logs = ShiftLog.by_shift(#shift)
names = logs.map(&:cardiologist).map(&:name)#.compact.uniq # you can add this if you want
h.content_tag :div do
h.content_tag :ul do
ul_content = ''.html_safe
names.each do |name|
ul_content << h.content_tag :li, name
end
ul_content
end
end
The thing is it works as block with the return statement: the last used/returned object will be put inside the content_tag.
Try to wrap each element of names in users_list method into <li> tag and join them in a string. To do this you need to change this line:
h.content_tag :div, names unless names.empty?
into this:
h.content_tag :div, names.map{|str| '<li>' + str + '</li>'}.join unless names.empty?

block methods in ruby

I am using a block method to print a list, but it is generating error.
class MyDataListBuilder
attr_accessor :object
def initialize(object)
#object = object
end
def column (&block)
content_tag :li, block.call
end
end
and using it as
<%= my_data_list_for #leads, [" :10", "Age:30", "Contact:140", "Phone:140", "Email:180", "Company:100", ""] do |l| %>
<%= l.column do %>
<%= object.age %>
<% end %>
<% end %>
other methods are
def list_headers(args=[])
args = Array.new(args)
columns = []
args.map { |o| columns << content_tag(:li, o.split(":").first, :style=>"width:#{o.split(":").second}px;") }
content_tag(:ul, columns.join(" ").html_safe, :class=>"list-headers")
end
def my_data_list_for(object, headers=[], &block)
arr = []
object.each do |o|
arr = capture(DataListHelper::MyDataListBuilder.new(o), &block)
end
content_tag(:ol, list_headers(headers) + arr, :class=>"data-list")
end
it is generating an error and i can not figure out why:
ActionView::Template::Error (undefined local variable or method `object' for #<#<Class:0xcaa1ca0>:0xca9ebf4>):
Please help me in it.
This solves the issue.
class MyDataListBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::CaptureHelper
attr_accessor :object, :output_buffer
def initialize(object)
#object = object
#output_buffer = nil
end
def column (&block)
if block_given?
content_tag(:li, capture(self, &block))
else
content_tag(:li, "")
end
end
end

Resources