1
;;; rails.el --- minor mode for editing RubyOnRails code
2
3
;; Copyright (C) 2006 Dmitry Galinsky <dima dot exe at gmail dot com>
4
5
;; Authors: Dmitry Galinsky <dima dot exe at gmail dot com>,
6
;;          Rezikov Peter <crazypit13 (at) gmail.com>
7
8
;; Keywords: ruby rails languages oop
9
;; $URL$
10
;; $Id$
11
12
;;; License
13
14
;; This program is free software; you can redistribute it and/or
15
;; modify it under the terms of the GNU General Public License
16
;; as published by the Free Software Foundation; either version 2
17
;; of the License, or (at your option) any later version.
18
19
;; This program is distributed in the hope that it will be useful,
20
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
;; GNU General Public License for more details.
23
24
;; You should have received a copy of the GNU General Public License
25
;; along with this program; if not, write to the Free Software
26
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27
28
;;; Code:
29
30
(unless (<= 22 emacs-major-version)
31
  (error
32
   (format "emacs-rails require CVS version of Emacs (future Emacs 22), and not be running on your Emacs %s.%s"
33
           emacs-major-version
34
           emacs-minor-version)))
35
36
(eval-when-compile
37
  (require 'speedbar)
38
  (require 'inf-ruby)
39
  (require 'ruby-mode)
40
  (require 'ruby-electric))
41
42
(require 'grep)
43
(require 'sql)
44
(require 'ansi-color)
45
(require 'etags)
46
47
(require 'predictive-prog-mode)
48
49
(require 'inflections)
50
51
(require 'rails-compat)
52
(require 'rails-project)
53
54
55
;;;;;;;;; Defining custom group before loading other file
56
57
(defgroup rails nil
58
  "Edit Rails projet with Emacs."
59
  :group 'programming
60
  :prefix "rails-")
61
62
;;;;;;;;; Loading most of the mode
63
64
(require 'rails-core)
65
(require 'rails-ruby)
66
(require 'rails-lib)
67
68
(require 'rails-cmd-proxy)
69
(require 'rails-navigation)
70
(require 'rails-find)
71
(require 'rails-scripts)
72
(require 'rails-rake)
73
(require 'rails-test)
74
(require 'rails-ws)
75
(require 'rails-log)
76
(require 'rails-ui)
77
(require 'rails-model-layout)
78
(require 'rails-controller-layout)
79
(require 'rails-features)
80
(require 'rails-lib-layout)
81
(require 'rails-spec)
82
(require 'rails-shoulda)
83
(require 'rails-refactoring)
84
85
;;;;;;;;;; Variable definition ;;;;;;;;;;
86
87
(defcustom rails-api-root ""
88
  "*Root of Rails API html documentation. Must be a local directory."
89
  :group 'rails
90
  :type 'string)
91
92
(defcustom rails-use-alternative-browse-url nil
93
  "Indicates an alternative way of loading URLs on Windows.
94
Try using the normal method before. If URLs invoked by the
95
program don't end up in the right place, set this option to
96
true."
97
  :group 'rails
98
  :type 'boolean)
99
100
(defcustom rails-browse-api-with-w3m nil
101
  "Indicates that the user wants to browse the Rails API using
102
Emacs w3m browser."
103
  :group 'rails
104
  :type 'boolean)
105
106
(defcustom rails-tags-command "ctags -e -a --Ruby-kinds=-f -o %s -R %s"
107
  "Command used to generate TAGS in Rails root"
108
  :group 'rails
109
  :type 'string)
110
111
(defcustom rails-ri-command "ri"
112
  "Command used to invoke the ri utility."
113
  :group 'rails
114
  :type 'string)
115
116
(defcustom rails-always-use-text-menus nil
117
  "Force the use of text menus by default."
118
  :group 'rails
119
  :type 'boolean)
120
121
(defcustom rails-text-menu-function nil
122
  "Which function to use to create text menus. nil means #'rails-core:ttm-menu"
123
  :group 'rails
124
  :type 'string)
125
126
(defcustom rails-ask-when-reload-tags nil
127
  "Indicates whether the user should confirm reload a TAGS table or not."
128
  :group 'rails
129
  :type 'boolean)
130
131
(defcustom rails-chm-file nil
132
  "Path to CHM documentation file on Windows, or nil."
133
  :group 'rails
134
  :type 'string)
135
136
(defcustom rails-ruby-command "ruby"
137
  "Ruby preferred command line invocation."
138
  :group 'rails
139
  :type 'string)
140
141
(defcustom rails-layout-template
142
  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
143
          \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
144
<html xmlns=\"http://www.w3.org/1999/xhtml\"
145
      xml:lang=\"en\" lang=\"en\">
146
  <head>
147
    <title></title>
148
    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
149
    <%= stylesheet_link_tag \"default\" %>
150
  </head>
151
152
  <body>
153
    <%= yield %>
154
  </body>
155
</html>"
156
  "Default html template for new rails layout"
157
  :group 'rails
158
  :type 'string)
159
160
(defcustom rails-enable-ruby-electric t
161
  "Indicates whether ruby electric minor mode should be enabled by default for ruby files"
162
  :group 'rails
163
  :type 'boolean)
164
165
(defcustom rails-number-of-lines-shown-when-opening-log-file 130
166
  "Specifies how many lines to show initially when opening a log file"
167
  :group 'rails
168
  :type 'integer)
169
170
(defvar rails-version "0.5.99.6")
171
(defvar rails-use-another-define-key nil)
172
(defvar rails-primary-switch-func nil)
173
(defvar rails-secondary-switch-func nil)
174
(defvar rails-required-lisp-eval-depth 1000) ; Specifies the minimum required value of max-lisp-eval-depth for rails mode to work
175
176
(defcustom rails-indent-and-complete t
177
  "Key to indent and complete."
178
  :group 'rails
179
  :type 'boolean)
180
181
(defvar rails-directory<-->types
182
  '((:controller       "app/controllers/")
183
    (:layout           "app/views/layouts/")
184
    (:view             "app/views/")
185
    (:observer         "app/models/" (lambda (file) (rails-core:observer-p file)))
186
    (:mailer           "app/models/" (lambda (file) (rails-core:mailer-p file)))
187
    (:model            "app/models/" (lambda (file) (and (not (rails-core:mailer-p file))
188
                                                         (not (rails-core:observer-p file)))))
189
    (:helper           "app/helpers/")
190
    (:unit-test        "vendor/plugins/.*/test/") ; needs to appear before more-general :plugin
191
    (:model            "vendor/plugins/.*/lib/") ; needs to appear before more-general :plugin
192
    (:plugin           "vendor/plugins/")
193
    (:unit-test        "test/unit/")
194
    (:functional-test  "test/functional/")
195
    (:integration-test  "test/integration/")
196
    (:fixture          "test/fixtures/")
197
    (:lib              "lib")
198
    (:rspec-controller "spec/controllers")
199
    (:rspec-controller "spec/requests")
200
    (:rspec-fixture    "spec/fixtures")
201
    (:rspec-lib        "spec/lib")
202
    (:rspec-model      "spec/models")
203
    (:migration        "db/migrate"))
204
  "Rails file types -- rails directories map")
205
206
(defcustom rails-environments '("development" "production" "test")
207
  "rails environments"
208
  :group 'rails
209
  :type '(repeat string))
210
211
(defcustom rails-default-environment (first rails-environments)
212
  "rails environment used by default"
213
  :group 'rails
214
  :type 'string)
215
216
(defvar rails-adapters-alist
217
  '(("mysql"      . sql-mysql)
218
    ("postgresql" . sql-postgres)
219
    ("sqlite3"    . sql-sqlite))
220
  "Sets emacs sql function for rails adapter names.")
221
222
(defcustom rails-tags-dirs '("app" "lib" "test" "db")
223
  "List of directories from RAILS_ROOT where ctags works."
224
  :group 'rails
225
  :type '(repeat string))
226
227
(defcustom rails-grep-extensions '("builder" "erb" "haml" "liquid" "mab" "rake" "rb" "rhtml" "rjs" "rxml" "yml" "feature" "js" "html" "rtex" "prawn")
228
  "List of file extensions which grep searches."
229
  :group 'rails
230
  :type '(repeat string))
231
232
(defcustom rails-templates-list
233
  '("html.erb" "erb" "js.rjs" "rjs" "xml.builder" "builder" "rhtml" "rxml" "html.haml" "haml" "html.liquid" "liquid" "html.mad" "mab" "pdf.rtex" "rtex" "pdf.prawn" "prawn")
234
  "List of view templates.  This first template is the default template."
235
  :group 'rails
236
  :type '(repeat string))
237
238
(defvar rails-error-regexp-alist
239
  '(
240
    (" /?\\(app/[a-z0-9._/]*\\):\\([0-9]+\\)" 1 2)
241
    (" /?\\(lib/[a-z0-9._/]*\\):\\([0-9]+\\)" 1 2)
242
    (" /?\\(test/[a-z0-9._/]*\\):\\([0-9]+\\)" 1 2)
243
    (" /?\\(db/[a-z0-9._/]*\\):\\([0-9]+\\)" 1 2)
244
    (" /?\\(vendor/[a-z0-9._/]*\\):\\([0-9]+\\)" 1 2)
245
    (" /?\\(app/[a-z0-9._/]*\\)" 1)
246
    (" /?\\(lib/[a-z0-9._/]*\\)" 1)
247
    (" /?\\(test/[a-z0-9._/]*\\)" 1)
248
    (" /?\\(db/[a-z0-9._/]*\\)" 1)
249
    (" /?\\(vendor/[a-z0-9._/]*\\)" 1)
250
    )
251
  "Rails specific compilation-error-regexp-alist.")
252
253
(defun rails-use-text-menu ()
254
  "If t use text menu, popup menu otherwise"
255
  (or (null window-system) rails-always-use-text-menus))
256
257
;;;;;;;; hack ;;;;
258
(defun rails-svn-status-into-root ()
259
  (interactive)
260
  (rails-project:with-root (root)
261
                           (svn-status root)))
262
263
(defun rails-git-status-into-root ()
264
  (interactive)
265
  (rails-project:with-root (root)
266
                           (git-status root)))
267
268
(defun rails-scm-status-into-root ()
269
  (interactive)
270
  (rails-project:with-root (root)
271
                           (cond ((file-directory-p (expand-file-name ".git" root))
272
                                  (rails-git-status-into-root))
273
                                 ((file-directory-p (expand-file-name ".svn" root))
274
                                  (rails-svn-status-into-root)))))
275
276
;; helper functions/macros
277
278
(defun backward-ruby-object ()
279
  (if (looking-back "[-a-zA-Z_#:*]+" (line-beginning-position) t)
280
      (goto-char (match-beginning 0))))
281
282
(defun forward-ruby-object (n)
283
  (if (> 0 n)
284
      (when (search-backward-regexp "[^-a-zA-Z_#:*][-a-zA-Z_#:*]+" nil t (- n))
285
	(forward-char)
286
	(point))
287
      (when (search-forward-regexp "[-a-zA-Z_#:*]+" nil t n)
288
	(goto-char (match-end 0)))))
289
290
(defun rails-search-doc (&optional item)
291
  (interactive)
292
  (setq item (if item item (thing-at-point 'ruby-object)))
293
  (unless item
294
    (setq item (read-string "Search symbol: ")))
295
  (if item
296
      (if (and rails-chm-file
297
               (file-exists-p rails-chm-file))
298
          (start-process "keyhh" "*keyhh*" "keyhh.exe" "-#klink"
299
                         (format "'%s'" item)  rails-chm-file)
300
          (with-current-buffer (get-buffer-create "*ri*")            
301
            (setq buffer-read-only nil)
302
            (erase-buffer)
303
            (message (concat "Please wait..."))
304
            (call-process rails-ri-command nil "*ri*" t "-T" "-f" "ansi" item)
305
            (ansi-color-apply-on-region (point-min) (point-max))
306
            (setq buffer-read-only t)
307
            (goto-char (point-min))
308
            (local-set-key "q" 'quit-window)
309
            (local-set-key [f1] 'rails-search-doc)
310
            (display-buffer (current-buffer))))))
311
312
(defun rails-create-tags()
313
  "Create tags file"
314
  (interactive)
315
  (rails-project:in-root
316
   (message "Creating TAGS, please wait...")
317
   (let ((tags-file-name (rails-core:file "TAGS")))
318
     (shell-command
319
      (format rails-tags-command tags-file-name
320
        (strings-join " " (mapcar #'rails-core:file rails-tags-dirs))))
321
     (flet ((yes-or-no-p (p) (if rails-ask-when-reload-tags
322
         (y-or-n-p p)
323
             t)))
324
       (visit-tags-table tags-file-name)))))
325
326
(defun rails-apply-for-buffer-type ()
327
 (let* ((type (rails-core:buffer-type))
328
        (name (substring (symbol-name type) 1))
329
        (minor-mode-name (format "rails-%s-minor-mode" name))
330
        (minor-mode-abbrev (concat minor-mode-name "-abbrev-table")))
331
   (when (require (intern minor-mode-name) nil t) ;; load new style minor mode rails-*-minor-mode
332
     (when (fboundp (intern minor-mode-name))
333
       (apply (intern minor-mode-name) (list t))
334
       (when (boundp (intern minor-mode-abbrev))
335
         (merge-abbrev-tables
336
          (symbol-value (intern minor-mode-abbrev))
337
          local-abbrev-table))))))
338
339
(defun rails-grep-project (regexp)
340
  "Find regexp in project."
341
  (interactive (progn (grep-compute-defaults)
342
                      (list (grep-read-regexp))))
343
  (rgrep regexp (mapconcat (lambda (ext) (format "*.%s" ext)) rails-grep-extensions " ") (rails-project:root)))
344
345
(defun rails-shell ()
346
  "Switch to the project inferior shell buffer."
347
  (interactive)
348
  (let ((default-directory (rails-project:root)))
349
    (shell (get-buffer-create (concat "*rails-" (rails-project:name) "-shell*")))))
350
351
;;;;;;;;;; Database integration ;;;;;;;;;;
352
353
(defstruct rails-db-conf adapter host database username password)
354
355
(defun rails-db-parameters (env)
356
  "Return database parameters for enviroment ENV"
357
  (with-temp-buffer
358
    (shell-command
359
     (format "ruby -r yaml -r erb -e 'YAML.load(ERB.new(ARGF.read).result)[\"%s\"].to_yaml.display' %s"
360
             env
361
             (rails-core:file "config/database.yml"))
362
     (current-buffer))
363
    (let ((answer
364
           (make-rails-db-conf
365
            :adapter  (yml-value "adapter")
366
            :host     (yml-value "host")
367
            :database (yml-value "database")
368
            :username (yml-value "username")
369
            :password (yml-value "password"))))
370
      answer)))
371
372
(defun rails-database-emacs-func (adapter)
373
  "Return the Emacs function for ADAPTER that, when run, will
374
+invoke the appropriate database server console."
375
  (cdr (assoc adapter rails-adapters-alist)))
376
377
(defun rails-read-enviroment-name (&optional default)
378
  "Read Rails enviroment with auto-completion."
379
  (completing-read "Environment name: " (list->alist rails-environments) nil nil default))
380
381
(defun* rails-run-sql (&optional env)
382
  "Run a SQL process for the current Rails project."
383
  (interactive (list (rails-read-enviroment-name "development")))
384
  (rails-project:with-root (root)
385
    (cd root)
386
    (if (bufferp (sql-find-sqli-buffer))
387
        (switch-to-buffer-other-window (sql-find-sqli-buffer))
388
      (let ((conf (rails-db-parameters env)))
389
        (let ((sql-database (rails-db-conf-database conf))
390
              (default-process-coding-system '(utf-8 . utf-8))
391
              (sql-server (rails-db-conf-host conf))
392
              (sql-user (rails-db-conf-username conf))
393
              (sql-password (rails-db-conf-password conf)))
394
          ;; Reload localy sql-get-login to avoid asking of confirmation of DB login parameters
395
          (flet ((sql-get-login (&rest pars) () t))
396
            (funcall (rails-database-emacs-func (rails-db-conf-adapter conf)))))))))
397
398
(defun rails-has-api-root ()
399
  "Test whether `rails-api-root' is configured or not, and offer to configure
400
it in case it's still empty for the project."
401
  (rails-project:with-root
402
   (root)
403
   (if (file-exists-p (rails-core:file (concat rails-api-root "/index.html")))
404
     t
405
     (unless (or (file-exists-p (rails-core:file "doc/api/index.html"))
406
                 (not (yes-or-no-p (concat "This project has no API documentation. "
407
                                           "Would you like to configure it now? "))))
408
       (let (clobber-gems)
409
         (message "This may take a while. Please wait...")
410
         (unless (file-exists-p (rails-core:file "vendor/rails"))
411
           (setq clobber-gems t)
412
           (message "Freezing gems...")
413
           (shell-command-to-string "rake rails:freeze:gems"))
414
         ;; Hack to allow generation of the documentation for Rails 1.0 and 1.1
415
         ;; See http://dev.rubyonrails.org/ticket/4459
416
         (unless (file-exists-p (rails-core:file "vendor/rails/activesupport/README"))
417
           (write-string-to-file (rails-core:file "vendor/rails/activesupport/README")
418
                                 "Placeholder"))
419
         (message "Generating documentation...")
420
         (shell-command-to-string "rake doc:rails")
421
         (if clobber-gems
422
           (progn
423
             (message "Unfreezing gems...")
424
             (shell-command-to-string "rake rails:unfreeze")))
425
         (message "Done...")))
426
     (if (file-exists-p (rails-core:file "doc/api/index.html"))
427
       (setq rails-api-root (rails-core:file "doc/api"))))))
428
429
(defun rails-browse-api ()
430
  "Browse Rails API on RAILS-API-ROOT."
431
  (interactive)
432
  (if (rails-has-api-root)
433
      (rails-browse-api-url (concat rails-api-root "/index.html"))
434
    (message "Please configure variable rails-api-root.")))
435
436
(defun rails-get-api-entries (name file sexp get-file-func)
437
  "Return all API entries named NAME in file FILE using SEXP to
438
find matches, and GET-FILE-FUNC to process the matches found."
439
  (if (file-exists-p (concat rails-api-root "/" file))
440
      (save-current-buffer
441
        (save-match-data
442
          (find-file (concat rails-api-root "/" file))
443
          (let* ((result
444
                  (loop for line in (split-string (buffer-string) "\n")
445
                        when (string-match (format sexp (regexp-quote name)) line)
446
                        collect (cons (match-string-no-properties 2 line)
447
                                      (match-string-no-properties 1 line)))))
448
            (kill-buffer (current-buffer))
449
            (when-bind (api-file (funcall get-file-func result))
450
                       (rails-browse-api-url (concat "file://" rails-api-root "/" api-file))))))
451
    (message "There are no API docs.")))
452
453
(defun rails-browse-api-class (class)
454
  "Browse the Rails API documentation for CLASS."
455
  (rails-get-api-entries
456
   class "fr_class_index.html" "<a href=\"\\(.*\\)\">%s<"
457
   (lambda (entries)
458
     (cond ((= 0 (length entries)) (progn (message "No API Rails doc for class %s." class) nil))
459
           ((= 1 (length entries)) (cdar entries))))))
460
461
(defun rails-browse-api-method (method)
462
  "Browse the Rails API documentation for METHOD."
463
  (rails-get-api-entries
464
   method "fr_method_index.html" "<a href=\"\\(.*\\)\">%s[ ]+(\\(.*\\))"
465
   (lambda (entries)
466
     (cond ((= 0 (length entries)) (progn (message "No API Rails doc for %s" method) nil))
467
           ((= 1 (length entries)) (cdar entries))
468
           (t (cdr (assoc (completing-read (format "Method %s from what class? " method) entries)
469
                          entries)))))))
470
471
(defun rails-browse-api-at-point ()
472
  "Open the Rails API documentation on the class or method at the current point.
473
The variable `rails-api-root' must be pointing to a local path
474
either in your project or elsewhere in the filesystem. The
475
function will also offer to build the documentation locally if
476
necessary."
477
  (interactive)
478
  (if (rails-has-api-root)
479
      (let ((current-symbol (prog2
480
                                (modify-syntax-entry ?: "w")
481
                                (thing-at-point 'sexp)
482
                              (modify-syntax-entry ?: "."))))
483
        (if current-symbol
484
            (if (capital-word-p current-symbol)
485
                (rails-browse-api-class current-symbol)
486
              (rails-browse-api-method current-symbol))))
487
    (message "Please configure \"rails-api-root\".")))
488
489
;;; Rails minor mode
490
491
(define-minor-mode rails-minor-mode
492
  "RubyOnRails"
493
  nil
494
  " RoR"
495
  rails-minor-mode-map
496
  (abbrev-mode -1)
497
  (make-local-variable 'tags-file-name)
498
  (make-local-variable 'rails-primary-switch-func)
499
  (make-local-variable 'rails-secondary-switch-func)
500
  (set (make-local-variable 'compile-command) "rake")
501
  (set (make-local-variable 'ffip-project-root) (rails-project:root))
502
  (set (make-local-variable 'ffip-regexp)
503
       (concat ".*\\(" (rails-core:regex-for-match-view)
504
               "\\|" (mapconcat #'car rails-auto-mode-alist "\\|")
505
               "\\|" (mapconcat (lambda (ext) (concat "\\." ext "$")) rails-refactoring-source-extensions "\\|")
506
               "\\|" (mapconcat (lambda (ext) (concat "\\." ext "$")) rails-grep-extensions "\\|")
507
               "\\)"))
508
  (set (make-local-variable 'ffip-patterns)
509
       (mapcar (lambda (ext) (concat "*." ext)) rails-grep-extensions))
510
  (rails-features:install))
511
512
;; hooks
513
514
(add-hook 'ruby-mode-hook
515
          (lambda ()
516
            (when (rails-project:root)
517
              (require 'rails-ruby)
518
              (require 'ruby-electric)
519
              (ruby-electric-mode (or rails-enable-ruby-electric -1))
520
              (ruby-hs-minor-mode t)
521
              (imenu-add-to-menubar "IMENU")
522
              (if rails-indent-and-complete
523
		(local-set-key (if rails-use-another-define-key
524
                                 (kbd "TAB") (kbd "<tab>"))
525
			       'indent-and-complete))
526
              (local-set-key (rails-key "f") '(lambda()
527
                                                (interactive)
528
                                                (mouse-major-mode-menu (rails-core:menu-position))))
529
              (local-set-key (kbd "C-:") 'ruby-toggle-string<>simbol)
530
              (local-set-key (if rails-use-another-define-key
531
                               (kbd "RET") (kbd "<return>"))
532
                             'ruby-newline-and-indent))))
533
534
(add-hook 'speedbar-mode-hook
535
          (lambda()
536
            (speedbar-add-supported-extension "\\.rb")))
537
538
(add-hook 'find-file-hooks
539
          (lambda()
540
            (rails-project:with-root
541
             (root)
542
             (progn
543
	       (if rails-indent-and-complete
544
		   (local-set-key (if rails-use-another-define-key
545
				      (kbd "TAB") (kbd "<tab>"))
546
				  'indent-and-complete))
547
               (rails-minor-mode t)
548
               (rails-apply-for-buffer-type)))))
549
550
;; Run rails-minor-mode in dired
551
552
(add-hook 'dired-mode-hook
553
          (lambda ()
554
            (if (rails-project:root)
555
                (rails-minor-mode t))))
556
557
(defvar rails-auto-mode-alist '(("\\.rb$"      . ruby-mode)
558
                                ("\\.rake$"    . ruby-mode)
559
                                ("\\.mab$"     . ruby-mode)
560
                                ("Rakefile$"   . ruby-mode)
561
                                ("Capfile$"    . ruby-mode)
562
                                ("\\.rxml$"    . ruby-mode)
563
                                ("\\.builder$" . ruby-mode)
564
                                ("\\.rjs$"     . ruby-mode)
565
                                ("\\.prawn$"   . ruby-mode)
566
                                ("\\.rhtml$"   . rhtml-mode)
567
                                ("\\.erb$"     . rhtml-mode)))
568
569
(dolist (pair rails-auto-mode-alist)
570
  (add-to-list 'auto-mode-alist pair)
571
  (modify-coding-system-alist 'file (car pair) 'utf-8))
572
573
(modify-coding-system-alist 'file (rails-core:regex-for-match-view) 'utf-8)
574
575
;; Some navigation breaks if max-lisp-eval-depth is not high enough, up it if too low
576
(setq max-lisp-eval-depth (max max-lisp-eval-depth rails-required-lisp-eval-depth))
577
578
(provide 'rails)