goldencobra 1.2.0 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/app/assets/images/goldencobra/chosen-sprite.png +0 -0
  2. data/app/assets/javascripts/goldencobra/active_admin.js +14 -23
  3. data/app/assets/javascripts/goldencobra/chosen.jquery.min.js +2 -10
  4. data/app/assets/stylesheets/goldencobra/chosen.css +312 -274
  5. data/app/controllers/goldencobra/application_controller.rb +8 -1
  6. data/app/controllers/goldencobra/articles_controller.rb +2 -20
  7. data/app/controllers/goldencobra/manage_controller.rb +6 -2
  8. data/app/helpers/goldencobra/articles_helper.rb +20 -0
  9. data/app/helpers/goldencobra/navigation_helper.rb +39 -13
  10. data/app/models/ability.rb +2 -0
  11. data/app/models/goldencobra/article.rb +5 -6
  12. data/app/models/goldencobra/article_image.rb +2 -0
  13. data/app/models/goldencobra/article_widget.rb +2 -0
  14. data/app/models/goldencobra/author.rb +2 -0
  15. data/app/models/goldencobra/comment.rb +2 -0
  16. data/app/models/goldencobra/domain.rb +16 -0
  17. data/app/models/goldencobra/help.rb +2 -0
  18. data/app/models/goldencobra/import_metadata.rb +2 -0
  19. data/app/models/goldencobra/location.rb +3 -1
  20. data/app/models/goldencobra/menue.rb +2 -2
  21. data/app/models/goldencobra/metatag.rb +2 -0
  22. data/app/models/goldencobra/permission.rb +2 -0
  23. data/app/models/goldencobra/role.rb +2 -0
  24. data/app/models/goldencobra/role_user.rb +2 -0
  25. data/app/models/goldencobra/setting.rb +2 -0
  26. data/app/models/goldencobra/tracking.rb +2 -0
  27. data/app/models/goldencobra/upload.rb +4 -2
  28. data/app/models/goldencobra/vita.rb +2 -0
  29. data/app/models/translation.rb +2 -0
  30. data/app/models/user.rb +2 -0
  31. data/app/models/visitor.rb +2 -0
  32. data/app/views/goldencobra/admin/articles/_articles_index.html.erb +3 -3
  33. data/app/views/goldencobra/admin/articles/_image_module_sidebar.html.erb +2 -4
  34. data/app/views/goldencobra/admin/articles/_link_checker.html.erb +2 -1
  35. data/app/views/goldencobra/admin/articles/_link_checker_index.html.erb +1 -0
  36. data/app/views/goldencobra/admin/articles/_select_article_type.html.erb +12 -13
  37. data/app/views/goldencobra/admin/articles/_widgets_sidebar.html.erb +3 -2
  38. data/app/views/goldencobra/admin/shared/_help.html.erb +15 -0
  39. data/app/views/goldencobra/admin/shared/_item.html.erb +3 -3
  40. data/app/views/goldencobra/articles/_headers.html.erb +6 -1
  41. data/app/views/goldencobra/articles/_navigation_menue.html.erb +6 -0
  42. data/app/views/goldencobra/articles/_show.html.erb +5 -5
  43. data/app/worker/articles_cache_worker.rb +1 -1
  44. data/config/initializers/liquid_tags.rb +47 -4
  45. data/config/initializers/papertrail_versions.rb +1 -0
  46. data/config/locales/active_admin.de.yml +8 -8
  47. data/config/locales/active_admin.en.yml +0 -4
  48. data/config/locales/activerecord.de.yml +1 -1
  49. data/config/locales/activerecord.en.yml +5 -2
  50. data/config/locales/article_types.de.yml +3 -16
  51. data/config/locales/article_types.en.yml +23 -0
  52. data/config/locales/devise.de.yml +0 -1
  53. data/config/locales/devise.en.yml +0 -1
  54. data/config/locales/en.yml +7 -0
  55. data/config/locales/goldencobra.de.yml +37 -1
  56. data/config/settings.yml +2 -0
  57. data/db/migrate/20131129143509_add_remote_to_goldencobra_menues.rb +5 -0
  58. data/db/migrate/20131216110750_add_main_to_goldencobra_domains.rb +7 -0
  59. data/lib/generators/goldencobra/articletype/templates/edit_index.html.erb +7 -7
  60. data/lib/goldencobra/select_current_client.rb +1 -0
  61. data/lib/goldencobra/version.rb +3 -1
  62. data/lib/tasks/cap_info.rb +30 -0
  63. data/lib/tasks/goldencobra_tasks.rake +2 -0
  64. data/lib/tasks/i18n.rake +2 -0
  65. data/lib/tasks/import.rake +47 -9
  66. metadata +17 -10
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Goldencobra
2
4
  class ApplicationController < ::ApplicationController
3
5
  before_filter :set_locale
@@ -53,9 +55,14 @@ module Goldencobra
53
55
  meta_tags[:noindex] = current_article.robots_no_index
54
56
  end
55
57
 
56
- if !current_article.canonical_url.blank?
58
+ if current_article.canonical_url.present?
57
59
  # with an canonical_url for rel="canonical"
58
60
  meta_tags[:canonical] = current_article.canonical_url
61
+ else
62
+ d = Goldencobra::Domain.main
63
+ if d.present? && @current_client.present? && @current_client.id != d.id
64
+ meta_tags[:canonical] = "http://#{d.hostname}#{current_article.public_url}"
65
+ end
59
66
  end
60
67
 
61
68
  set_meta_tags meta_tags
@@ -12,13 +12,14 @@ module Goldencobra
12
12
  end
13
13
 
14
14
  def show_cache_path
15
+ current_client_id = @current_client.try(:id).to_s
15
16
  geo_cache = Goldencobra::Setting.for_key("goldencobra.geocode_ip_address") == "true" && session[:user_location].present? && session[:user_location].city.present? ? session[:user_location].city.parameterize.underscore : "no_geo"
16
17
  date_cache = Goldencobra::Setting.for_key("goldencobra.article.max_cache_24h") == "true" ? Date.today.strftime("%Y%m%d") : "no_date"
17
18
  art_cache = @article ? @article.cache_key : "no_art"
18
19
  user_cache = current_user.present? ? current_user.id : "no_user"
19
20
  flash_message = session.present? && session['flash'].present? ? Time.now.to_i : ""
20
21
  auth_code = params[:auth_token].present? ? 'with_auth' : ''
21
- "g/#{I18n.locale.to_s}/#{geo_cache}/#{user_cache}/#{date_cache}/#{params[:article_id]}/#{art_cache}_#{params[:pdf]}_#{params[:frontend_tags]}__#{params[:iframe]}#{flash_message}_#{auth_code}"
22
+ "c-#{current_client_id}/g/#{I18n.locale.to_s}/#{geo_cache}/#{user_cache}/#{date_cache}/#{params[:article_id]}/#{art_cache}_#{params[:pdf]}_#{params[:frontend_tags]}__#{params[:iframe]}#{flash_message}_#{auth_code}"
22
23
  end
23
24
 
24
25
 
@@ -79,25 +80,6 @@ module Goldencobra
79
80
  end
80
81
  end
81
82
 
82
- # def convert_to_pdf
83
- # if @article
84
- # require 'net/http'
85
- # require "uri"
86
- # uid = Goldencobra::Setting.for_key("goldencobra.html2pdf_uid")
87
- # uri = URI.parse("http://html2pdf.ikusei.de/converter/new.xml?&print_layout=true&uid=#{uid}&url=#{@article.absolute_public_url}#{CGI::escape('?pdf=1')}")
88
- # logger.debug(uri)
89
- # http = Net::HTTP.new(uri.host, uri.port)
90
- # request = Net::HTTP::Get.new(uri.request_uri)
91
- # response = http.request(request)
92
- # doc = Nokogiri::HTML(response.body)
93
- # file = doc.at_xpath("//file-name").text
94
- # redirect_to "http://html2pdf.ikusei.de#{file}"
95
- # else
96
- # render :text => "404", :status => 404
97
- # end
98
- # end
99
-
100
-
101
83
  def sitemap
102
84
  if Goldencobra::Setting.for_key("goldencobra.use_ssl") == "true"
103
85
  @use_ssl = "s"
@@ -31,8 +31,12 @@ module Goldencobra
31
31
  end
32
32
 
33
33
  def call_for_support
34
- Goldencobra::ConfirmationMailer.send_support_mail(params[:link]).deliver
35
- render :text => "200"
34
+ if current_user || current_visitor
35
+ Goldencobra::ConfirmationMailer.send_support_mail(params[:link]).deliver
36
+ render :text => "200"
37
+ else
38
+ render :text => "401"
39
+ end
36
40
  end
37
41
 
38
42
  end
@@ -19,6 +19,26 @@ module Goldencobra
19
19
  end
20
20
 
21
21
 
22
+ #Parse text for a single Word and make a link to an Article to this Word as a Subarticle of a given Article
23
+ def parse_glossar_entries(content,tag_name, parent_article_id=nil)
24
+ glossar_parent = nil
25
+ if parent_article_id
26
+ glossar_parent = Goldencobra::Article.find_by_id(parent_article_id)
27
+ glossar_article = glossar_parent.children.where(:breadcrumb => tag_name).first
28
+ else
29
+ glossar_article = Goldencobra::Article.where(:breadcrumb => tag_name).first
30
+ end
31
+ unless glossar_article
32
+ glossar_article = Goldencobra::Article.create(:title => tag_name, :breadcrumb => tag_name, :article_type => "Default Show", :parent => glossar_parent)
33
+ end
34
+
35
+ if glossar_article.present?
36
+ replace_with = "<a href='#{glossar_article.public_url}' class='glossar'>#{tag_name}</a>"
37
+ content = content.gsub(/\b(?<!\/)#{tag_name}(?!<)\b/, "#{replace_with}")
38
+ end
39
+ end
40
+
41
+
22
42
  def render_article_image_gallery
23
43
  if @article
24
44
  result = ""
@@ -20,7 +20,6 @@ module Goldencobra
20
20
  end
21
21
  end
22
22
 
23
- #
24
23
  # navigation_menu("Hauptmenue", :depth => 1, :class => "top", :id => "menue1", :offset => 1 )
25
24
  # depth: 0 = unlimited, 1 = self, 2 = self and children 1. grades, 3 = self and up to children 2.grades
26
25
  # offset: number of levels to skip, 0 = none
@@ -58,19 +57,29 @@ module Goldencobra
58
57
 
59
58
  current_depth = master_menue.ancestry_depth
60
59
  #Check for Permission
61
- if params[:frontend_tags] && params[:frontend_tags].class != String && params[:frontend_tags][:format] && params[:frontend_tags][:format] == "email"
62
- #Wenn format email, dann gibt es keinen realen webseit besucher
60
+ begin
61
+ if params.present? && params[:frontend_tags].present? && params[:frontend_tags].class != String && params[:frontend_tags][:format] && params[:frontend_tags][:format] == "email"
62
+ #Wenn format email, dann gibt es keinen realen webseit besucher
63
+ ability = Ability.new()
64
+ else current_user.present? || current_visitor.present?
65
+ operator = current_user || current_visitor
66
+ ability = Ability.new(operator)
67
+ end
68
+ rescue
63
69
  ability = Ability.new()
64
- else
65
- operator = current_user || current_visitor
66
- ability = Ability.new(operator)
67
70
  end
71
+
68
72
  if !ability.can?(:read, master_menue)
69
73
  return ""
70
74
  end
75
+
71
76
  if master_menue.present?
72
77
  content = ""
73
- subtree_menues = master_menue.subtree.after_depth(current_depth + offset).to_depth(current_depth + depth).active.includes(:permissions).includes(:image)
78
+ if current_article.present?
79
+ subtree_menues = master_menue.subtree.after_depth(current_depth).to_depth(current_depth + depth).active.includes(:permissions).includes(:image)
80
+ else
81
+ subtree_menues = master_menue.subtree.after_depth(current_depth + offset).to_depth(current_depth + depth).active.includes(:permissions).includes(:image)
82
+ end
74
83
  subtree_menues = subtree_menues.to_a.delete_if{|a| !ability.can?(:read, a)}
75
84
 
76
85
  current_depth = 1
@@ -90,7 +99,7 @@ module Goldencobra
90
99
  private
91
100
 
92
101
  def menue_roots(menue_array)
93
- min_of_layers = menue_array.map{|a| a.ancestry.split("/").count }.min
102
+ min_of_layers = menue_array.map{|a| a.ancestry.to_s.split("/").count }.min
94
103
  return menue_array.select{|a| a.ancestry.to_s.split("/").count == min_of_layers }
95
104
  end
96
105
 
@@ -104,13 +113,18 @@ module Goldencobra
104
113
  else
105
114
  child_target_link = child.target.gsub("\"",'')
106
115
  end
107
- child_link = content_tag(:a, child.title, :href => child_target_link)
116
+ if child.remote
117
+ link_options = {"data-remote" => "true",:href => child_target_link}
118
+ else
119
+ link_options = {:href => child_target_link}
120
+ end
121
+ child_link = content_tag(:a, child.title, link_options )
108
122
  image_link = child.image.present? ? image_tag(child.image.image(:original)) : ""
109
- child_link = child_link + content_tag(:a, image_link, :href => child_target_link, :class => "navigtion_link_imgage_wrapper") unless options[:show_image] == false
110
- child_link = child_link + content_tag(:a, child.description_title, :href => child_target_link, :class => "navigtion_link_description_title") unless options[:show_description_title] == false
123
+ child_link = child_link + content_tag(:a, image_link, link_options.merge(:class => "navigtion_link_imgage_wrapper")) unless options[:show_image] == false
124
+ child_link = child_link + content_tag(:a, child.description_title, link_options.merge(:class => "navigtion_link_description_title")) unless options[:show_description_title] == false
111
125
  template = Liquid::Template.parse(child.description)
112
126
  child_link = child_link + content_tag("div", raw(template.render(Goldencobra::Article::LiquidParser)), :class => "navigtion_link_description") unless options[:show_description] == false
113
- child_link = child_link + content_tag(:a, child.call_to_action_name, :href => child_target_link, :class => "navigtion_link_call_to_action_name") unless options[:show_call_to_action_name] == false
127
+ child_link = child_link + content_tag(:a, child.call_to_action_name, link_options.merge(:class => "navigtion_link_call_to_action_name")) unless options[:show_call_to_action_name] == false
114
128
 
115
129
  current_depth += 1
116
130
  child_elements = menue_children(child, subtree_menues)
@@ -127,7 +141,19 @@ module Goldencobra
127
141
  child_link = child_link + content_tag(:ul, raw(content_level), :class => "level_#{current_depth} children_#{visible_child_element_count}" )
128
142
  end
129
143
  end
130
- return content_tag(:li, raw(child_link),"data-id" => child.id , :class => "#{ visible_child_element_count > 0 ? 'has_children' : ''} #{child.has_active_child?(request, subtree_menues) ? 'has_active_child' : ''} #{child.is_active?(request) ? 'active' : ''} #{child.css_class.gsub(/\W/,' ')}".squeeze(' ').strip)
144
+
145
+ # to have path from context, when liquid witohut request
146
+ # logger.info("-------------")
147
+ # logger.info(options[:liquid_url_path].present?)
148
+ # logger.info(options[:liquid_url_path])
149
+ # logger.info(request.blank?)
150
+ # logger.info("-------------")
151
+ # if options[:liquid_url_path].present? && request.blank?
152
+ # path_obj = Struct.new(:path)
153
+ # request = path_obj.new(options[:liquid_url_path])
154
+ # end
155
+
156
+ return content_tag(:li, raw(child_link), "data-id" => child.id, :class => "#{ visible_child_element_count > 0 ? 'has_children' : '' } #{ (child.has_active_child?(request, subtree_menues) ? 'has_active_child' : '') if request.present? } #{ (child.is_active?(request) ? 'active' : '') if request.present? } #{ child.css_class.gsub(/\W/,' ') }".squeeze(' ').strip)
131
157
  end
132
158
 
133
159
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  class Ability
2
4
  include CanCan::Ability
3
5
 
@@ -77,6 +77,7 @@ module Goldencobra
77
77
 
78
78
  accepts_nested_attributes_for :metatags, :allow_destroy => true, :reject_if => proc { |attributes| attributes['value'].blank? }
79
79
  accepts_nested_attributes_for :article_images, :allow_destroy => true
80
+ accepts_nested_attributes_for :images, :allow_destroy => true
80
81
  accepts_nested_attributes_for :permissions, :allow_destroy => true
81
82
  accepts_nested_attributes_for :author, :allow_destroy => true
82
83
 
@@ -85,7 +86,7 @@ module Goldencobra
85
86
  friendly_id :for_friendly_name, use: [:slugged] #, :history
86
87
  web_url :external_url_redirect
87
88
  has_paper_trail
88
- liquid_methods :title, :created_at, :updated_at, :subtitle, :context_info, :id
89
+ liquid_methods :title, :created_at, :updated_at, :subtitle, :context_info, :id, :frontend_tags
89
90
 
90
91
  validates_presence_of :title, :article_type
91
92
  validates_format_of :url_name, :with => /\A[\w\d-]+\Z/, allow_blank: true
@@ -266,7 +267,6 @@ module Goldencobra
266
267
  end
267
268
 
268
269
  Goldencobra::Article.init_image_methods
269
-
270
270
  def image(position="standard", size="original")
271
271
  any_images = self.article_images.where(position: position)
272
272
  if any_images.any? && any_images.first.image && any_images.first.image.image
@@ -276,6 +276,7 @@ module Goldencobra
276
276
  end
277
277
  end
278
278
 
279
+
279
280
  def respond_to_all?(method_name)
280
281
  begin
281
282
  return eval("self.#{method_name}.present?")
@@ -342,9 +343,7 @@ module Goldencobra
342
343
  @list_of_articles = @list_of_articles.flatten.shuffle
343
344
  elsif self.sort_order == "Alphabetical"
344
345
  @list_of_articles = @list_of_articles.flatten.sort_by{|article| article.title }
345
- elsif self.sort_order == "Created_at"
346
- @list_of_articles = @list_of_articles.flatten.sort_by{|article| article.created_at.to_i }
347
- elsif self.respond_to?(self.sort_order)
346
+ elsif self.respond_to?(self.sort_order.downcase)
348
347
  sort_order = self.sort_order.downcase
349
348
  @list_of_articles = @list_of_articles.flatten.sort_by{|article| article.respond_to?(sort_order) ? article.send(sort_order) : article }
350
349
  elsif self.sort_order.include?(".")
@@ -693,7 +692,7 @@ module Goldencobra
693
692
  else
694
693
  Goldencobra::Article.active.each do |article|
695
694
  article.updated_at = Time.now
696
- article.save
695
+ article.without_versioning :save
697
696
  end
698
697
  end
699
698
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_article_images
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_article_widgets
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Goldencobra
2
4
  class Author < ActiveRecord::Base
3
5
  has_many :article
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_comments
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Goldencobra
2
4
  class Domain < ActiveRecord::Base
3
5
 
@@ -7,6 +9,20 @@ module Goldencobra
7
9
  validates_presence_of :hostname
8
10
  validates_uniqueness_of :hostname
9
11
 
12
+ before_save :mark_as_main
13
+
14
+ def self.main
15
+ Goldencobra::Domain.where(:main => true).first
16
+ end
17
+
18
+ def mark_as_main
19
+ if self.main == true
20
+ Goldencobra::Domain.where("id <> #{self.id.to_i}").each do |a|
21
+ a.main = false
22
+ a.save
23
+ end
24
+ end
25
+ end
10
26
 
11
27
  def self.current
12
28
  Thread.current[:current_client]
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_helps
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Goldencobra
2
4
  class ImportMetadata < ActiveRecord::Base
3
5
  ImportDataFunctions = []
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_locations
@@ -39,7 +41,7 @@ module Goldencobra
39
41
  end
40
42
 
41
43
  def skip_geocoding_once_or_always
42
- self.skip_geocode || self.manual_geocoding
44
+ (Goldencobra::Setting.for_key("goldencobra.locations.geocoding") == "false" ) || self.skip_geocode || self.manual_geocoding
43
45
  end
44
46
  end
45
47
  end
@@ -23,7 +23,7 @@ module Goldencobra
23
23
  class Menue < ActiveRecord::Base
24
24
  attr_accessible :title, :target, :css_class, :active, :ancestry, :parent_id,
25
25
  :sorter, :description, :call_to_action_name, :description_title, :image_attributes, :image_id,
26
- :permissions_attributes
26
+ :permissions_attributes, :remote
27
27
  has_ancestry :orphan_strategy => :rootify, :cache_depth => true
28
28
  belongs_to :image, :class_name => Goldencobra::Upload, :foreign_key => "image_id"
29
29
 
@@ -66,7 +66,7 @@ module Goldencobra
66
66
 
67
67
  def has_active_child?(request, subtree_menues)
68
68
  @has_active_child_result ||= {}
69
- @has_active_child_result[request.path.squeeze("/").split("?")[0]] ||= has_active_descendant?(subtree_menues,request)
69
+ @has_active_child_result[request.path.squeeze("/").split("?")[0]] ||= has_active_descendant?(subtree_menues, request)
70
70
  end
71
71
 
72
72
  def has_active_descendant?(subtree_menues,request)
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_metatags
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_permissions
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_roles
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_roles_users
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_settings
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_trackings
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_uploads
@@ -50,8 +52,8 @@ module Goldencobra
50
52
 
51
53
  def unzip_files
52
54
  if self.image_file_name.include?(".zip") && File.exists?(self.image.path)
53
- require 'zip/zip'
54
- zipped_files = Zip::ZipFile.open(self.image.path)
55
+ require 'zip'
56
+ zipped_files = Zip::File.open(self.image.path)
55
57
  int = 0
56
58
  zipped_files.each do |zipped_file|
57
59
  int = int + 1
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: goldencobra_vita
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: translations
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: users
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # == Schema Information
2
4
  #
3
5
  # Table name: visitors