{"id":3006,"date":"2015-10-13T12:36:59","date_gmt":"2015-10-13T08:36:59","guid":{"rendered":"http:\/\/www.dhtmlx.com\/blog\/?p=3006"},"modified":"2025-05-19T14:04:45","modified_gmt":"2025-05-19T11:04:45","slug":"recurring-events-scheduler-ruby-on-rails","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/recurring-events-scheduler-ruby-on-rails\/","title":{"rendered":"Recurring Events in dhtmlxScheduler with Ruby on Rails &#8211; Part II"},"content":{"rendered":"<p>Recently we&#8217;ve shared the detailed tutorial that explains how to use our <a href=\"https:\/\/dhtmlx.com\/blog\/use-dhtmlxscheduler-ruby-rails-part-1-tutorial\/\" target=\"_blank\">scheduling calendar with Ruby on Rails<\/a>. As promised, today we share the second part of this guide &#8211; you&#8217;ll be able to add recurring events to your calendar.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/Scheduler-recurring.png\" alt=\"Scheduler-recurring\" width=\"600\" height=\"472\" class=\"aligncenter size-full wp-image-3009\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/Scheduler-recurring.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/Scheduler-recurring-300x236.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><br \/>\n<!--more--><br \/>\nBefore we start, please follow the instructions described <a href=\"https:\/\/dhtmlx.com\/blog\/use-dhtmlxscheduler-ruby-rails-part-1-tutorial\/\" target=\"_blank\">in the first part of the tutorial about Ruby on Rails<\/a> to prepare your scheduler for the further steps. When finished, you may proceed with adding recurring events:<\/p>\n<p><strong>Step 1.<\/strong> For recurring events we need three additional fields: <\/p>\n<p>&#8211; rec_type (stores recurring logic);<br \/>\n&#8211; event_pid (parent ID of a series of events);<br \/>\n&#8211; event_length (a real length of a series of events).<\/p>\n<p>Also we need to remove the old model. For this we run the following:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"rails codecolorer\">rails <span class=\"kw5\">destroy<\/span> model Event<\/div><\/div>\n<p><strong>Step 2.<\/strong> Use the following command to create a new model:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"rails codecolorer\">rails generate model Event start_date:datetime end_date:datetime text:string rec_type:string event_length:integer event_pid:integer<\/div><\/div>\n<p><strong>Step 3.<\/strong> Remove the events table from the database or remove db\/development.sqlite3.<\/p>\n<p>After that we need to run a migration:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"rails codecolorer\">rake db:migrate<\/div><\/div>\n<p><strong>Step 4.<\/strong> Open app\/controllers\/home_controller.rb<\/p>\n<p>Here we change \u201cdb_action\u201d action and \u201cdata\u201d for saving and loading of recurring events:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;height:600px;\"><div class=\"rails codecolorer\"><span class=\"kw1\">class<\/span> HomeController <span class=\"sy0\">&lt;<\/span> ApplicationController<br \/>\n&nbsp;<span class=\"kw1\">def<\/span> index<br \/>\n&nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp;<span class=\"kw1\">def<\/span> data<br \/>\n&nbsp; &nbsp;events = Event.<span class=\"me1\">all<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"kw5\">render<\/span> <span class=\"re3\">:json<\/span> <span class=\"sy0\">=&gt;<\/span> events.<span class=\"me1\">map<\/span> <span class=\"br0\">&#123;<\/span><span class=\"sy0\">|<\/span>event<span class=\"sy0\">|<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:id<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">id<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:start_date<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">start_date<\/span>.<span class=\"me1\">to_formatted_s<\/span><span class=\"br0\">&#40;<\/span><span class=\"re3\">:db<\/span><span class=\"br0\">&#41;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:end_date<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">end_date<\/span>.<span class=\"me1\">to_formatted_s<\/span><span class=\"br0\">&#40;<\/span><span class=\"re3\">:db<\/span><span class=\"br0\">&#41;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:text<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">text<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:rec_type<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">rec_type<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:event_length<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">event_length<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:event_pid<\/span> <span class=\"sy0\">=&gt;<\/span> event.<span class=\"me1\">event_pid<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp;<span class=\"kw1\">def<\/span> db_action<br \/>\n&nbsp; &nbsp;mode = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'!nativeeditor_status'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;id = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'id'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;start_date = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'start_date'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;end_date = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'end_date'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;text = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'text'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;rec_type = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'rec_type'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;event_length = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'event_length'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;event_pid = params<span class=\"br0\">&#91;<\/span><span class=\"st0\">'event_pid'<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp;tid = id<br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"kw1\">case<\/span> mode<br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">when<\/span> <span class=\"st0\">'inserted'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event = Event.<span class=\"me1\">create<\/span> <span class=\"re3\">:start_date<\/span> <span class=\"sy0\">=&gt;<\/span> start_date, <span class=\"re3\">:end_date<\/span> <span class=\"sy0\">=&gt;<\/span> end_date, <span class=\"re3\">:text<\/span> <span class=\"sy0\">=&gt;<\/span> text,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:rec_type<\/span> <span class=\"sy0\">=&gt;<\/span> rec_type, <span class=\"re3\">:event_length<\/span> <span class=\"sy0\">=&gt;<\/span> event_length, <span class=\"re3\">:event_pid<\/span> <span class=\"sy0\">=&gt;<\/span> event_pid<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;tid = event.<span class=\"me1\">id<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> rec_type == <span class=\"st0\">'none'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mode = <span class=\"st0\">'deleted'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">when<\/span> <span class=\"st0\">'deleted'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> rec_type != <span class=\"st0\">''<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Event.<span class=\"me1\">where<\/span><span class=\"br0\">&#40;<\/span>event_pid: id<span class=\"br0\">&#41;<\/span>.<span class=\"kw5\">destroy_all<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> event_pid != <span class=\"nu0\">0<\/span> <span class=\"kw1\">and<\/span> event_pid != <span class=\"st0\">''<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;event = Event.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">rec_type<\/span> = <span class=\"st0\">'none'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"kw5\">save<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Event.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span>.<span class=\"kw5\">destroy<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">when<\/span> <span class=\"st0\">'updated'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> rec_type != <span class=\"st0\">''<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Event.<span class=\"me1\">where<\/span><span class=\"br0\">&#40;<\/span>event_pid: id<span class=\"br0\">&#41;<\/span>.<span class=\"kw5\">destroy_all<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<span class=\"kw1\">end<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event = Event.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">start_date<\/span> = start_date<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">end_date<\/span> = end_date<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">text<\/span> = text<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">rec_type<\/span> = rec_type<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">event_length<\/span> = event_length<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"me1\">event_pid<\/span> = event_pid<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;event.<span class=\"kw5\">save<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">end<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"kw5\">render<\/span> <span class=\"re3\">:json<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:type<\/span> <span class=\"sy0\">=&gt;<\/span> mode,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:sid<\/span> <span class=\"sy0\">=&gt;<\/span> id,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"re3\">:tid<\/span> <span class=\"sy0\">=&gt;<\/span> tid,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp;<span class=\"kw1\">end<\/span><br \/>\n<span class=\"kw1\">end<\/span><\/div><\/div>\n<p><strong>Step 5.<\/strong> Open config\/initializers\/assets.rb and add dhtmlxscheduler_recurring extension to the  precompile array.<\/p>\n<p>For this we need to add this line:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"rails codecolorer\">Rails.<span class=\"me1\">application<\/span>.<span class=\"me1\">config<\/span>.<span class=\"me1\">assets<\/span>.<span class=\"me1\">precompile<\/span> <span class=\"sy0\">+<\/span>= <span class=\"sy0\">%<\/span>w<span class=\"br0\">&#40;<\/span> ext<span class=\"sy0\">\/<\/span>dhtmlxscheduler_recurring.<span class=\"me1\">js<\/span> <span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p><strong>Step 6.<\/strong> Open views\/layouts\/application.html.erb and include dhtmlxscheduler_recurring.js extension.<\/p>\n<div class=\"codecolorer-container html4strict default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"html4strict codecolorer\"><span class=\"sc0\">&lt;!DOCTYPE html&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">html<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">head<\/span>&gt;<\/span><br \/>\n&nbsp;<span class=\"sc2\">&lt;<span class=\"kw2\">title<\/span>&gt;<\/span>Scheduler on Rails<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">title<\/span>&gt;<\/span><br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> csrf_meta_tags %&gt;<\/span><br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> stylesheet_link_tag &nbsp; &nbsp;<span class=\"st0\">'application'<\/span>, <span class=\"kw3\">media<\/span>: <span class=\"st0\">'all'<\/span>, <span class=\"st0\">'data-turbolinks-track'<\/span> <span class=\"sy0\">=<\/span>&gt;<\/span> true %&gt;<br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> stylesheet_link_tag <span class=\"st0\">'dhtmlxscheduler'<\/span>, <span class=\"kw3\">media<\/span>: <span class=\"st0\">'all'<\/span>, <span class=\"st0\">'data-turbolinks-track'<\/span> <span class=\"sy0\">=<\/span>&gt;<\/span> true %&gt;<br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> javascript_include_tag <span class=\"st0\">'application'<\/span>, <span class=\"st0\">'data-turbolinks-track'<\/span> <span class=\"sy0\">=<\/span>&gt;<\/span> true %&gt;<br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> javascript_include_tag <span class=\"st0\">'dhtmlxscheduler'<\/span>, <span class=\"st0\">'data-turbolinks-track'<\/span> <span class=\"sy0\">=<\/span>&gt;<\/span> true %&gt;<br \/>\n&nbsp;<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> javascript_include_tag <span class=\"st0\">'ext\/dhtmlxscheduler_recurring'<\/span>, <span class=\"st0\">'data-turbolinks-track'<\/span> <span class=\"sy0\">=<\/span>&gt;<\/span> true %&gt;<br \/>\n&nbsp;<br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">head<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">body<\/span>&gt;<\/span><br \/>\n<br \/>\n<span class=\"sc2\">&lt;%<span class=\"sy0\">=<\/span> yield %&gt;<\/span><br \/>\n<br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">body<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">html<\/span>&gt;<\/span><\/div><\/div>\n<p><strong>Final Step 7.<\/strong> Well, we need to run the server once again to check our scheduler with recurring events:<\/p>\n<div class=\"codecolorer-container rails default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"rails codecolorer\">rails server<\/div><\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/recurring-events-on-rails.png\" alt=\"recurring events on rails\" width=\"600\" height=\"385\" class=\"aligncenter size-full wp-image-3010\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/recurring-events-on-rails.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2015\/10\/recurring-events-on-rails-300x192.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>If you follow the given instructions, you should now have a ready-to-use scheduler with recurring events that perfectly works with Rails framework. As you can see, there isn&#8217;t much code and integration with this framework is performed quite easy. Apart from the described features, <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/\" target=\"_blank\">dhtmlxScheduler<\/a> has very extended functionality, and it won&#8217;t be difficult to create a full-featured scheduling calendar that will work with Ruby on Rails.<\/p>\n<p>You&#8217;re welcome to leave your comments and ask questions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently we&#8217;ve shared the detailed tutorial that explains how to use our scheduling calendar with Ruby on Rails. As promised, today we share the second part of this guide &#8230;<\/p>\n","protected":false},"author":2,"featured_media":3804,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,71,1],"tags":[33,14,36,15],"class_list":["post-3006","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-posts-for-codeproject-com","category-tutorials","category-uncategorized","tag-all-posts","tag-tips","tag-ruby-on-rails","tag-dhtmlxscheduler"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=3006"}],"version-history":[{"count":3,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3006\/revisions"}],"predecessor-version":[{"id":13866,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3006\/revisions\/13866"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/3804"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=3006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=3006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=3006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}