crystal-ext 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Rakefile +66 -0
- data/lib/abstract_interface/controller_helper.rb +30 -0
- data/lib/abstract_interface/form_builders/abstract_form_builder.rb +79 -0
- data/lib/abstract_interface/form_builders/themed_form_builder.rb +46 -0
- data/lib/abstract_interface/form_builders/themed_form_tag_builder.rb +13 -0
- data/lib/abstract_interface/haml_builder.rb +56 -0
- data/lib/abstract_interface/model_stub.rb +20 -0
- data/lib/abstract_interface/support.rb +56 -0
- data/lib/abstract_interface/theme.rb +37 -0
- data/lib/abstract_interface/view_builder.rb +158 -0
- data/lib/abstract_interface/view_helper.rb +31 -0
- data/lib/abstract_interface.rb +78 -0
- data/lib/common_interface/MIT-LICENSE +20 -0
- data/lib/common_interface/README.md +51 -0
- data/lib/common_interface/app/controllers/theme_controller.rb +65 -0
- data/lib/common_interface/app/controllers/theme_site_controller.rb +2 -0
- data/lib/common_interface/app/views/layouts/theme.html.erb +1 -0
- data/lib/common_interface/app/views/layouts/theme.js.erb +11 -0
- data/lib/common_interface/app/views/theme/_dialog.html.haml +7 -0
- data/lib/common_interface/app/views/theme/_popup.html.haml +4 -0
- data/lib/common_interface/app/views/theme/aspects.html.haml +32 -0
- data/lib/common_interface/app/views/theme/basic.html.haml +123 -0
- data/lib/common_interface/app/views/theme/dialog.js.erb +1 -0
- data/lib/common_interface/app/views/theme/folder.html.haml +45 -0
- data/lib/common_interface/app/views/theme/help.html.haml +7 -0
- data/lib/common_interface/app/views/theme/index.html.haml +24 -0
- data/lib/common_interface/app/views/theme/items.html.haml +91 -0
- data/lib/common_interface/app/views/theme/list.html.haml +23 -0
- data/lib/common_interface/app/views/theme/page/_folder.html.haml +10 -0
- data/lib/common_interface/app/views/theme/page/_note.html.haml +4 -0
- data/lib/common_interface/app/views/theme/page/_toolbar.html.haml +5 -0
- data/lib/common_interface/app/views/theme/page.html.haml +19 -0
- data/lib/common_interface/app/views/theme/popup.js.erb +1 -0
- data/lib/common_interface/app/views/theme/selector.html.haml +38 -0
- data/lib/common_interface/app/views/theme/style.html.erb +113 -0
- data/lib/common_interface/app/views/theme/tmp.html.erb +31 -0
- data/lib/common_interface/app/views/theme/user.html.haml +16 -0
- data/lib/common_interface/app/views/theme_shared/_comments.html.haml +11 -0
- data/lib/common_interface/app/views/theme_shared/_core_tools.html.haml +6 -0
- data/lib/common_interface/app/views/theme_shared/_line_previews.html.haml +39 -0
- data/lib/common_interface/app/views/theme_shared/_paginator.html.haml +7 -0
- data/lib/common_interface/app/views/theme_shared/_tools.html.haml +27 -0
- data/lib/common_interface/app/views/theme_shared/_top_navigation_bottom.html.haml +32 -0
- data/lib/common_interface/app/views/theme_site/blog.html.haml +13 -0
- data/lib/common_interface/app/views/theme_site/home.html.haml +9 -0
- data/lib/common_interface/app/views/theme_site/post.html.haml +11 -0
- data/lib/common_interface/app/views/theme_site/style.html.haml +9 -0
- data/lib/common_interface/app/views/themes/default/_application_t.html.haml +29 -0
- data/lib/common_interface/app/views/themes/default/_help_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/aspects/_comment_t.html.haml +14 -0
- data/lib/common_interface/app/views/themes/default/aspects/_controls_t.html.haml +3 -0
- data/lib/common_interface/app/views/themes/default/aspects/_details_t.html.haml +6 -0
- data/lib/common_interface/app/views/themes/default/aspects/_discussion_t.html.haml +9 -0
- data/lib/common_interface/app/views/themes/default/aspects/_paginator_t.html.haml +8 -0
- data/lib/common_interface/app/views/themes/default/aspects/_tag_selector_t.html.haml +11 -0
- data/lib/common_interface/app/views/themes/default/basic/_bottom_panel_t.html.haml +9 -0
- data/lib/common_interface/app/views/themes/default/basic/_dialog_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_divider_t.html.haml +2 -0
- data/lib/common_interface/app/views/themes/default/basic/_html_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_inplace_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_message_t.html.haml +3 -0
- data/lib/common_interface/app/views/themes/default/basic/_more_t.html.haml +5 -0
- data/lib/common_interface/app/views/themes/default/basic/_narrow_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_navigation_t.html.haml +9 -0
- data/lib/common_interface/app/views/themes/default/basic/_popup_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_text_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/basic/_title_t.html.haml +3 -0
- data/lib/common_interface/app/views/themes/default/basic/_tool_t.html.haml +4 -0
- data/lib/common_interface/app/views/themes/default/basic/_top_panel_t.html.haml +18 -0
- data/lib/common_interface/app/views/themes/default/components/_basic_list_item_t.html.haml +4 -0
- data/lib/common_interface/app/views/themes/default/components/_basic_list_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/components/_table_row_t.html.haml +5 -0
- data/lib/common_interface/app/views/themes/default/components/_table_t.html.haml +12 -0
- data/lib/common_interface/app/views/themes/default/components/_tabs_item_t.html.haml +4 -0
- data/lib/common_interface/app/views/themes/default/components/_tabs_t.html.haml +4 -0
- data/lib/common_interface/app/views/themes/default/components/_toolbar_t.html.haml +14 -0
- data/lib/common_interface/app/views/themes/default/forms/_begin_t.html.erb +3 -0
- data/lib/common_interface/app/views/themes/default/forms/_end_t.html.erb +3 -0
- data/lib/common_interface/app/views/themes/default/forms/_errors_t.html.haml +5 -0
- data/lib/common_interface/app/views/themes/default/forms/_field_t.html.haml +19 -0
- data/lib/common_interface/app/views/themes/default/forms/_line_t.html.haml +6 -0
- data/lib/common_interface/app/views/themes/default/items/_file_t.html.haml +19 -0
- data/lib/common_interface/app/views/themes/default/items/_folder_t.html.haml +23 -0
- data/lib/common_interface/app/views/themes/default/items/_line_t.html.haml +34 -0
- data/lib/common_interface/app/views/themes/default/items/_list_item_t.html.haml +16 -0
- data/lib/common_interface/app/views/themes/default/items/_list_t.html.haml +35 -0
- data/lib/common_interface/app/views/themes/default/items/_note_t.html.haml +16 -0
- data/lib/common_interface/app/views/themes/default/items/_page_t.html.haml +29 -0
- data/lib/common_interface/app/views/themes/default/items/_selector_t.html.haml +18 -0
- data/lib/common_interface/app/views/themes/default/items/_thumb_t.html.haml +12 -0
- data/lib/common_interface/app/views/themes/default/items/_user_t.html.haml +12 -0
- data/lib/common_interface/app/views/themes/default/layout_templates/_dashboard_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/default/layout_templates/_default_t.html.haml +11 -0
- data/lib/common_interface/app/views/themes/default/metadata.rb +117 -0
- data/lib/common_interface/app/views/themes/simple_organization/_application_js_t.html.erb +12 -0
- data/lib/common_interface/app/views/themes/simple_organization/_application_t.html.erb +45 -0
- data/lib/common_interface/app/views/themes/simple_organization/_help_t.html.erb +1 -0
- data/lib/common_interface/app/views/themes/simple_organization/aspects/_comment_t.html.haml +21 -0
- data/lib/common_interface/app/views/themes/simple_organization/aspects/_discussion_t.html.haml +14 -0
- data/lib/common_interface/app/views/themes/simple_organization/aspects/_paginator_t.html.haml +5 -0
- data/lib/common_interface/app/views/themes/simple_organization/aspects/_tag_selector_t.html.haml +10 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_bottom_panel_t.html.erb +12 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_divider_t.html.erb +3 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_message_t.html.erb +7 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_more_t.html.haml +5 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_navigation_t.html.erb +15 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_text_t.html.haml +1 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_tool_t.html.erb +9 -0
- data/lib/common_interface/app/views/themes/simple_organization/basic/_top_panel_t.html.erb +14 -0
- data/lib/common_interface/app/views/themes/simple_organization/items/_line_t.html.haml +17 -0
- data/lib/common_interface/app/views/themes/simple_organization/items/_note_t.html.haml +16 -0
- data/lib/common_interface/app/views/themes/simple_organization/items/_selector_t.html.haml +11 -0
- data/lib/common_interface/app/views/themes/simple_organization/layout_templates/_default_t.html.erb +20 -0
- data/lib/common_interface/app/views/themes/simple_organization/layout_templates/_home_t.html.erb +14 -0
- data/lib/common_interface/app/views/themes/simple_organization/metadata.rb +193 -0
- data/lib/common_interface/asset_packages.yml +89 -0
- data/lib/common_interface/init.rb +21 -0
- data/lib/common_interface/lib/common_interface_helper.rb +49 -0
- data/lib/common_interface/public/common_interface/images/img1.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img1_200.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img1_icon.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img1_thumb.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img2.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img2_200.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img2_icon.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img2_thumb.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img3.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img3_200.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img3_icon.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/img3_thumb.jpg +0 -0
- data/lib/common_interface/public/common_interface/images/video_icon.png +0 -0
- data/lib/common_interface/public/common_interface/js/aspects.js +0 -0
- data/lib/common_interface/public/common_interface/js/basic.js +229 -0
- data/lib/common_interface/public/common_interface/js/files_upload.js +115 -0
- data/lib/common_interface/public/common_interface/js/items.js +118 -0
- data/lib/common_interface/public/common_interface/js/style.js +50 -0
- data/lib/common_interface/public/common_interface/lib/jquery.elastic.js +117 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/blank.gif +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_close.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_loading.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_nav_left.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_nav_right.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_e.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_n.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_ne.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_nw.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_s.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_se.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_sw.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_shadow_w.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_title_left.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_title_main.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_title_over.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancy_title_right.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancybox-x.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancybox-y.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/fancybox.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/jquery.easing-1.3.pack.js +72 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/jquery.fancybox-1.3.1.js +1077 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/jquery.fancybox.css +363 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/jquery.fancybox.js +44 -0
- data/lib/common_interface/public/common_interface/lib/jquery.fancybox/jquery.mousewheel-3.0.2.pack.js +13 -0
- data/lib/common_interface/public/common_interface/lib/jquery.form.js +660 -0
- data/lib/common_interface/public/common_interface/lib/jquery.hoverIntent.js +111 -0
- data/lib/common_interface/public/common_interface/lib/jquery.jgrowl/jquery.jgrowl.css +128 -0
- data/lib/common_interface/public/common_interface/lib/jquery.jgrowl/jquery.jgrowl.js +307 -0
- data/lib/common_interface/public/common_interface/lib/jquery.js +4376 -0
- data/lib/common_interface/public/common_interface/lib/jquery.json.js +178 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/cancel.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/jquery.swfupload.js +64 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/style.css +8 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/swfupload/swfupload.js +980 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/swfupload/swfupload.queue.js +98 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/swfupload/swfupload.swf +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.swfupload/swfupload/wdp_buttons_upload_61x22.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.template.js +255 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-icons_222222_256x240.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-icons_228ef1_256x240.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-icons_ef8c08_256x240.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-icons_ffd27a_256x240.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/jquery.ui.css +406 -0
- data/lib/common_interface/public/common_interface/lib/jquery.ui/jquery.ui.js +71 -0
- data/lib/common_interface/public/common_interface/themes/default/_aspects.scss +58 -0
- data/lib/common_interface/public/common_interface/themes/default/_basic.scss +228 -0
- data/lib/common_interface/public/common_interface/themes/default/_components.scss +151 -0
- data/lib/common_interface/public/common_interface/themes/default/_custom_reset.scss +12 -0
- data/lib/common_interface/public/common_interface/themes/default/_elastic.scss +72 -0
- data/lib/common_interface/public/common_interface/themes/default/_items.scss +88 -0
- data/lib/common_interface/public/common_interface/themes/default/_mixins.scss +39 -0
- data/lib/common_interface/public/common_interface/themes/default/_special.scss +34 -0
- data/lib/common_interface/public/common_interface/themes/default/_variables.scss +15 -0
- data/lib/common_interface/public/common_interface/themes/default/_yui_reset.scss +127 -0
- data/lib/common_interface/public/common_interface/themes/default/elastic.js +307 -0
- data/lib/common_interface/public/common_interface/themes/default/elastic.print.css +8 -0
- data/lib/common_interface/public/common_interface/themes/default/reset.css +157 -0
- data/lib/common_interface/public/common_interface/themes/default/reset.scss +5 -0
- data/lib/common_interface/public/common_interface/themes/default/style.css +580 -0
- data/lib/common_interface/public/common_interface/themes/default/style.js +84 -0
- data/lib/common_interface/public/common_interface/themes/default/style.scss +11 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/_fixes.scss +130 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/_original.scss +852 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/comment-arrow.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/comment-gravatar.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/comment-reply.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/logo-small.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/logo.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/main-two-columns-left.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/main-two-columns.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/sample-event.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/sample-gravatar.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/sample-image.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/img/sample-thumbnail.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/archives.html +389 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/comments.html +486 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/empty-page.html +107 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/comment-arrow.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/comment-gravatar.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/comment-reply.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/logo-small.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/logo.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/main-two-columns-left.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/main-two-columns.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/sample-event.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/sample-gravatar.gif +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/sample-image.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/img/sample-thumbnail.jpg +0 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/index.html +307 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/left-sidebar.html +307 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/no-subnavigation.html +290 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/single-column.html +209 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/style-demo.html +355 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/original/style.css +658 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/style.css +965 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/style.scss +2 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/tmp/comments.html +486 -0
- data/lib/common_interface/public/common_interface/themes/simple_organization/tmp/tmp.html +307 -0
- data/lib/common_interface/spec/controllers/theme_controller_spec.rb +50 -0
- data/lib/common_interface/spec/spec.opts +4 -0
- data/lib/common_interface/spec/spec_helper.rb +1 -0
- data/lib/common_interface/tmp/html.html +39 -0
- data/lib/common_interface/tmp/js.js +78 -0
- data/lib/mongo_mapper_ext/db_config.rb +76 -0
- data/lib/mongo_mapper_ext/hacks/fixes.rb +32 -0
- data/lib/mongo_mapper_ext/hacks/time_measuring.rb +44 -0
- data/lib/mongo_mapper_ext/micelaneous.rb +9 -0
- data/lib/mongo_mapper_ext/migrate.rake +33 -0
- data/lib/mongo_mapper_ext/migration.rb +108 -0
- data/lib/mongo_mapper_ext/mongo_mapper.rb +25 -0
- data/lib/mongo_mapper_ext/plugins/attributes_cache.rb +22 -0
- data/lib/mongo_mapper_ext/plugins/default_scope.rb +76 -0
- data/lib/mongo_mapper_ext/plugins/micelaneous.rb +81 -0
- data/lib/mongo_mapper_ext/spec_helper.rb +10 -0
- data/lib/mongo_mapper_ext/view_helpers.rb +10 -0
- data/lib/mongo_mapper_ext.rb +29 -0
- data/lib/rails_ext/README.markdown +13 -0
- data/lib/rails_ext/action_controller/global_path_prefix.rb +56 -0
- data/lib/rails_ext/action_controller/micelaneous.rb +118 -0
- data/lib/rails_ext/action_controller/persistent_params.rb +96 -0
- data/lib/rails_ext/action_controller/redirect_helper.rb +14 -0
- data/lib/rails_ext/action_controller/reload_page.rb +7 -0
- data/lib/rails_ext/action_controller.rb +19 -0
- data/lib/rails_ext/action_view/common_helper.rb +96 -0
- data/lib/rails_ext/action_view/ruby_template.rb +13 -0
- data/lib/rails_ext/action_view.rb +5 -0
- data/lib/rails_ext/active_record/merge_default_scope/hash_poser.rb +40 -0
- data/lib/rails_ext/active_record/merge_default_scope.rb +16 -0
- data/lib/rails_ext/active_record/micelaneous.rb +14 -0
- data/lib/rails_ext/active_record.rb +7 -0
- data/lib/rails_ext/active_support/micelaneous.rb +7 -0
- data/lib/rails_ext/active_support.rb +1 -0
- data/lib/rails_ext/asset_packager/action_view.rb +47 -0
- data/lib/rails_ext/asset_packager/asset_packager.rb +112 -0
- data/lib/rails_ext/asset_packager/jsmin.rb +205 -0
- data/lib/rails_ext/asset_packager/tasks.rb +27 -0
- data/lib/rails_ext/asset_packager.rb +4 -0
- data/lib/rails_ext/basic/handy_environment.rb +45 -0
- data/lib/rails_ext/basic/user_error.rb +12 -0
- data/lib/rails_ext/basic.rb +6 -0
- data/lib/rails_ext/hacks/ajax_flash.rb +9 -0
- data/lib/rails_ext/hacks/ajax_redirect_to.rb +19 -0
- data/lib/rails_ext/hacks/defer_static_javascripts.rb +18 -0
- data/lib/rails_ext/hacks/global_path_prefix.rb +33 -0
- data/lib/rails_ext/hacks/link_to.rb +105 -0
- data/lib/rails_ext/hacks/merge_default_scope.rb +20 -0
- data/lib/rails_ext/hacks/persistent_params.rb +16 -0
- data/lib/rails_ext/hacks/rjs_layout.rb +2 -0
- data/lib/rails_ext/micelaneous/addressable_uri.rb +45 -0
- data/lib/rails_ext/micelaneous/config_files.rb +18 -0
- data/lib/rails_ext/micelaneous/create_public_symlinks.rb +11 -0
- data/lib/rails_ext/micelaneous/defer_static_javascripts.rb +50 -0
- data/lib/rails_ext/micelaneous/email_config.rb +8 -0
- data/lib/rails_ext/micelaneous/i18n_helper.rb +143 -0
- data/lib/rails_ext/micelaneous/rails_require.rb +4 -0
- data/lib/rails_ext/micelaneous/safe_hash.rb +104 -0
- data/lib/rails_ext/micelaneous.rb +17 -0
- data/lib/rails_ext/public/rails_ext/rails_ext.css +2 -0
- data/lib/rails_ext/public/rails_ext/rails_ext.js +283 -0
- data/lib/rails_ext/spec/mongo_mapper_ext/micelaneous_plugin_spec.rb +56 -0
- data/lib/rails_ext/spec/mongo_mapper_ext/micelaneous_spec.rb +51 -0
- data/lib/rails_ext/spec/mongo_mapper_ext/mongo_mapper_migration_spec.rb +76 -0
- data/lib/rails_ext/spec/mongo_mapper_ext/scope_spec.rb +125 -0
- data/lib/rails_ext/spec/rails_ext/haml_builder_spec.rb +136 -0
- data/lib/rails_ext/spec/rails_ext/safe_hash_spec.rb +71 -0
- data/lib/rails_ext/spec/spec.opts +3 -0
- data/lib/sunspot/mongo_mapper/adapters.rb +79 -0
- data/lib/sunspot/mongo_mapper/searchable.rb +409 -0
- data/lib/sunspot/spec_helper.rb +11 -0
- data/readme.md +1 -0
- data/spec/mongo_mapper_ext/micelaneous_plugin_spec.rb +56 -0
- data/spec/mongo_mapper_ext/micelaneous_spec.rb +51 -0
- data/spec/mongo_mapper_ext/mongo_mapper_migration_spec.rb +76 -0
- data/spec/mongo_mapper_ext/scope_spec.rb +125 -0
- data/spec/rails_ext/haml_builder_spec.rb +136 -0
- data/spec/rails_ext/safe_hash_spec.rb +71 -0
- data/spec/spec.opts +4 -0
- metadata +405 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'spec'
|
|
2
|
+
|
|
3
|
+
require 'ruby_ext'
|
|
4
|
+
require 'active_support'
|
|
5
|
+
require "#{File.dirname __FILE__}/../../lib/abstract_interface/haml_builder"
|
|
6
|
+
|
|
7
|
+
require 'facets/openobject'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Don't use should ==, it doesn't works with OpenObject
|
|
12
|
+
#
|
|
13
|
+
describe "HamlBuilder use cases" do
|
|
14
|
+
class TemplateStub
|
|
15
|
+
def self.capture &block
|
|
16
|
+
block.call
|
|
17
|
+
self.output
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
attr_accessor :output
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def build *args, &block
|
|
26
|
+
opt = args.extract_options!
|
|
27
|
+
args.size.should! :be_in, 0..1
|
|
28
|
+
opt[:content] = args.first if args.size == 1
|
|
29
|
+
|
|
30
|
+
r = AbstractInterface::HamlBuilder.get_input(TemplateStub, opt, &block)
|
|
31
|
+
convert_to_hashes r
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def convert_to_hashes value
|
|
35
|
+
if value.is_a? OpenObject
|
|
36
|
+
r = {}
|
|
37
|
+
value.each do |k, v|
|
|
38
|
+
r[k] = convert_to_hashes v
|
|
39
|
+
end
|
|
40
|
+
r
|
|
41
|
+
else
|
|
42
|
+
value
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "hash" do
|
|
47
|
+
(build do |o|
|
|
48
|
+
o.a :b
|
|
49
|
+
end).should == {:a => :b}
|
|
50
|
+
|
|
51
|
+
build(:a => :b).should == {:a => :b}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "array" do
|
|
55
|
+
(build do |a|
|
|
56
|
+
a.add 1
|
|
57
|
+
a.add 2
|
|
58
|
+
end).should == {:content => [1, 2]}
|
|
59
|
+
|
|
60
|
+
(build do |o|
|
|
61
|
+
o.a :b
|
|
62
|
+
o.ar do |a|
|
|
63
|
+
a.add 1
|
|
64
|
+
a.add 2
|
|
65
|
+
end
|
|
66
|
+
end).should == {:a => :b, :ar => [1, 2]}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "capture" do
|
|
70
|
+
build("value").should == {:content => "value"}
|
|
71
|
+
|
|
72
|
+
(build do
|
|
73
|
+
TemplateStub.output = "value"
|
|
74
|
+
end).should == {:content => "value"}
|
|
75
|
+
|
|
76
|
+
(build do |o|
|
|
77
|
+
o.content do
|
|
78
|
+
TemplateStub.output = "value"
|
|
79
|
+
end
|
|
80
|
+
end).should == {:content => "value"}
|
|
81
|
+
|
|
82
|
+
(build do |o|
|
|
83
|
+
o.value do
|
|
84
|
+
TemplateStub.output = "value"
|
|
85
|
+
end
|
|
86
|
+
end).should == {:value => "value"}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "invalid usage" do
|
|
90
|
+
lambda{
|
|
91
|
+
build "value" do
|
|
92
|
+
TemplateStub.output = "value"
|
|
93
|
+
end
|
|
94
|
+
}.should raise_error(/Invalid usage!/)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "merge" do
|
|
98
|
+
(build :a => :b do
|
|
99
|
+
TemplateStub.output = "value"
|
|
100
|
+
end).should == {:a => :b, :content => "value"}
|
|
101
|
+
|
|
102
|
+
(build :a => :b do |o|
|
|
103
|
+
o.c :d
|
|
104
|
+
end).should == {:a => :b, :c => :d}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "nested" do
|
|
108
|
+
(build :a => :b do |o|
|
|
109
|
+
o.a do |o|
|
|
110
|
+
o.b :c
|
|
111
|
+
end
|
|
112
|
+
end).should == {
|
|
113
|
+
:a => {:b => :c}
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "complex" do
|
|
118
|
+
(build :a => :b do |o|
|
|
119
|
+
o.hs do |h|
|
|
120
|
+
h.c :d
|
|
121
|
+
end
|
|
122
|
+
o.ar do |a|
|
|
123
|
+
a.add 1
|
|
124
|
+
a.add 2
|
|
125
|
+
end
|
|
126
|
+
o.html do
|
|
127
|
+
TemplateStub.output = "value"
|
|
128
|
+
end
|
|
129
|
+
end).should == {
|
|
130
|
+
:a => :b,
|
|
131
|
+
:hs => {:c => :d},
|
|
132
|
+
:ar => [1, 2],
|
|
133
|
+
:html => 'value'
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec'
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require "#{File.dirname __FILE__}/../../lib/rails_ext/micelaneous/safe_hash"
|
|
5
|
+
|
|
6
|
+
describe "SafeHash and SafeNil" do
|
|
7
|
+
it "should allow check for value presence" do
|
|
8
|
+
h = SafeHash.new :a => :b
|
|
9
|
+
h.a?.should be_true
|
|
10
|
+
h.b?.should be_false
|
|
11
|
+
|
|
12
|
+
h.should include(:a)
|
|
13
|
+
h.should_not include(:b)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should allow owerride values" do
|
|
17
|
+
h = SafeHash.new :a => :b
|
|
18
|
+
h[:b] = :c
|
|
19
|
+
h.b!.should == :c
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "general behaviour" do
|
|
23
|
+
h = SafeHash.new :key => :value
|
|
24
|
+
|
|
25
|
+
h.key.should == :value
|
|
26
|
+
h.key(:missing).should == :value
|
|
27
|
+
|
|
28
|
+
h[:key].should == :value
|
|
29
|
+
h[:key, :missing].should == :value
|
|
30
|
+
|
|
31
|
+
h['key'].should == :value
|
|
32
|
+
h['key', :missing].should == :value
|
|
33
|
+
|
|
34
|
+
h.a.b.c[:d].e('missing').should == 'missing'
|
|
35
|
+
h.a.b.c[:d][:e, 'missing'].should == 'missing'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should build hierarchies of SafeHash" do
|
|
39
|
+
h = SafeHash.new :a => {:a => :b}
|
|
40
|
+
|
|
41
|
+
h.a.a.should == :b
|
|
42
|
+
h.a.missing.b.c('missing').should == 'missing'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should require setting if ! used" do
|
|
46
|
+
h = SafeHash.new :a => :v, :b => {:c => :v}
|
|
47
|
+
|
|
48
|
+
h.a!.should == :v
|
|
49
|
+
h.b.c!.should == :v
|
|
50
|
+
h.b!.c!.should == :v
|
|
51
|
+
|
|
52
|
+
lambda{h.j!}.should raise_error(/No key j/)
|
|
53
|
+
lambda{h.j.b.c!}.should raise_error(/No key c/)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should be able to update itself" do
|
|
57
|
+
h = SafeHash.new
|
|
58
|
+
h.b?.should be_false
|
|
59
|
+
h[:a] = :a
|
|
60
|
+
h.a!.should == :a
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should implement include?" do
|
|
64
|
+
h = SafeHash.new :a => :b
|
|
65
|
+
h.include?(:a).should be_true
|
|
66
|
+
h.include?('a').should be_true
|
|
67
|
+
h.include?(:b).should be_false
|
|
68
|
+
|
|
69
|
+
h.b.include?(:a).should be_false
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Sunspot #:nodoc:
|
|
2
|
+
module MongoMapper #:nodoc:
|
|
3
|
+
#
|
|
4
|
+
# This module provides Sunspot Adapter implementations for MongoMapper
|
|
5
|
+
# models.
|
|
6
|
+
#
|
|
7
|
+
module Adapters
|
|
8
|
+
class MongoMapperInstanceAdapter < Sunspot::Adapters::InstanceAdapter
|
|
9
|
+
#
|
|
10
|
+
# Return the primary key for the adapted instance
|
|
11
|
+
#
|
|
12
|
+
# ==== Returns
|
|
13
|
+
#
|
|
14
|
+
# Integer:: Database ID of model
|
|
15
|
+
#
|
|
16
|
+
def id
|
|
17
|
+
@instance.id
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class MongoMapperDataAccessor < Sunspot::Adapters::DataAccessor
|
|
22
|
+
# options for the find
|
|
23
|
+
attr_accessor :include, :select
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Set the fields to select from the database. This will be passed
|
|
27
|
+
# to MongoMapper.
|
|
28
|
+
#
|
|
29
|
+
# ==== Parameters
|
|
30
|
+
#
|
|
31
|
+
# value<Mixed>:: String of comma-separated columns or array of columns
|
|
32
|
+
#
|
|
33
|
+
def select=(value)
|
|
34
|
+
value = value.join(', ') if value.respond_to?(:join)
|
|
35
|
+
@select = value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Get one MongoMapper instance out of the database by ID
|
|
40
|
+
#
|
|
41
|
+
# ==== Parameters
|
|
42
|
+
#
|
|
43
|
+
# id<String>:: Database ID of model to retreive
|
|
44
|
+
#
|
|
45
|
+
# ==== Returns
|
|
46
|
+
#
|
|
47
|
+
# MongoMapper::Base:: MongoMapper model
|
|
48
|
+
#
|
|
49
|
+
def load(id)
|
|
50
|
+
@clazz.first(options_for_find.merge(:id => id))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Get a collection of MongoMapper instances out of the database by ID
|
|
55
|
+
#
|
|
56
|
+
# ==== Parameters
|
|
57
|
+
#
|
|
58
|
+
# ids<Array>:: Database IDs of models to retrieve
|
|
59
|
+
#
|
|
60
|
+
# ==== Returns
|
|
61
|
+
#
|
|
62
|
+
# Array:: Collection of MongoMapper models
|
|
63
|
+
#
|
|
64
|
+
def load_all(ids)
|
|
65
|
+
@clazz.all(options_for_find.merge(:id => ids))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def options_for_find
|
|
71
|
+
returning({}) do |options|
|
|
72
|
+
options[:include] = @include unless @include.blank?
|
|
73
|
+
options[:select] = @select unless @select.blank?
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
module Sunspot #:nodoc:
|
|
2
|
+
module MongoMapper #:nodoc:
|
|
3
|
+
#
|
|
4
|
+
# This module adds Sunspot functionality to MongoMapper models. As well as
|
|
5
|
+
# providing class and instance methods, it optionally adds lifecycle hooks
|
|
6
|
+
# to automatically add and remove models from the Solr index as they are
|
|
7
|
+
# created and destroyed.
|
|
8
|
+
#
|
|
9
|
+
module Searchable
|
|
10
|
+
class <<self
|
|
11
|
+
def included(base) #:nodoc:
|
|
12
|
+
base.module_eval do
|
|
13
|
+
extend(ActsAsMethods)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module ActsAsMethods
|
|
19
|
+
#
|
|
20
|
+
# Makes a class searchable if it is not already, or adds search
|
|
21
|
+
# configuration if it is. Note that the options passed in are only used
|
|
22
|
+
# the first time this method is called for a particular class; so,
|
|
23
|
+
# search should be defined before activating any mixins that extend
|
|
24
|
+
# search configuration.
|
|
25
|
+
#
|
|
26
|
+
# The block passed into this method is evaluated by the
|
|
27
|
+
# <code>Sunspot.setup</code> method. See the Sunspot documentation for
|
|
28
|
+
# complete information on the functionality provided by that method.
|
|
29
|
+
#
|
|
30
|
+
# ==== Options (+options+)
|
|
31
|
+
#
|
|
32
|
+
# :auto_index<Boolean>::
|
|
33
|
+
# Automatically index models in Solr when they are saved.
|
|
34
|
+
# Default: true
|
|
35
|
+
# :auto_remove<Boolean>::
|
|
36
|
+
# Automatically remove models from the Solr index when they are
|
|
37
|
+
# destroyed. <b>Setting this option to +false+ is not recommended
|
|
38
|
+
# </b>(see the README).
|
|
39
|
+
# :ignore_attribute_changes_of<Array>::
|
|
40
|
+
# Define attributes, that should not trigger a reindex of that
|
|
41
|
+
# object. Usual suspects are updated_at or counters.
|
|
42
|
+
# :include<Mixed>::
|
|
43
|
+
# Define default MongoMapper includes, set this to allow MongoMapper
|
|
44
|
+
# to load required associations when indexing. See MongoMapper's
|
|
45
|
+
# documentation on eager-loading for examples on how to set this
|
|
46
|
+
# Default: []
|
|
47
|
+
#
|
|
48
|
+
# ==== Example
|
|
49
|
+
#
|
|
50
|
+
# class Post < MongoMapper::Base
|
|
51
|
+
# searchable do
|
|
52
|
+
# text :title, :body
|
|
53
|
+
# string :sort_title do
|
|
54
|
+
# title.downcase.sub(/^(an?|the)/, '')
|
|
55
|
+
# end
|
|
56
|
+
# integer :blog_id
|
|
57
|
+
# time :updated_at
|
|
58
|
+
# end
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
def searchable(options = {}, &block)
|
|
62
|
+
Sunspot.setup(self, &block)
|
|
63
|
+
|
|
64
|
+
if searchable?
|
|
65
|
+
sunspot_options[:include].concat(Util::Array(options[:include]))
|
|
66
|
+
else
|
|
67
|
+
extend ClassMethods
|
|
68
|
+
include InstanceMethods
|
|
69
|
+
|
|
70
|
+
class_inheritable_hash :sunspot_options
|
|
71
|
+
|
|
72
|
+
unless options[:auto_index] == false
|
|
73
|
+
before_save :maybe_mark_for_auto_indexing
|
|
74
|
+
after_save :maybe_auto_index
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
unless options[:auto_remove] == false
|
|
78
|
+
after_destroy do |searchable|
|
|
79
|
+
searchable.remove_from_index
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
options[:include] = Util::Array(options[:include])
|
|
83
|
+
|
|
84
|
+
self.sunspot_options = options
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
#
|
|
89
|
+
# This method is defined on all MongoMapper::Base subclasses. It
|
|
90
|
+
# is false for classes on which #searchable has not been called, and
|
|
91
|
+
# true for classes on which #searchable has been called.
|
|
92
|
+
#
|
|
93
|
+
# ==== Returns
|
|
94
|
+
#
|
|
95
|
+
# +false+
|
|
96
|
+
#
|
|
97
|
+
def searchable?
|
|
98
|
+
false
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
module ClassMethods
|
|
103
|
+
def self.extended(base) #:nodoc:
|
|
104
|
+
class <<base
|
|
105
|
+
alias_method :search, :solr_search unless method_defined? :search
|
|
106
|
+
alias_method :search_ids, :solr_search_ids unless method_defined? :search_ids
|
|
107
|
+
alias_method :remove_all_from_index, :solr_remove_all_from_index unless method_defined? :remove_all_from_index
|
|
108
|
+
alias_method :remove_all_from_index!, :solr_remove_all_from_index! unless method_defined? :remove_all_from_index!
|
|
109
|
+
alias_method :reindex, :solr_reindex unless method_defined? :reindex
|
|
110
|
+
alias_method :index, :solr_index unless method_defined? :index
|
|
111
|
+
alias_method :index_orphans, :solr_index_orphans unless method_defined? :index_orphans
|
|
112
|
+
alias_method :clean_index_orphans, :solr_clean_index_orphans unless method_defined? :clean_index_orphans
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
#
|
|
116
|
+
# Search for instances of this class in Solr. The block is delegated to
|
|
117
|
+
# the Sunspot.search method - see the Sunspot documentation for the full
|
|
118
|
+
# API.
|
|
119
|
+
#
|
|
120
|
+
# ==== Example
|
|
121
|
+
#
|
|
122
|
+
# Post.search(:include => [:blog]) do
|
|
123
|
+
# keywords 'best pizza'
|
|
124
|
+
# with :blog_id, 1
|
|
125
|
+
# order :updated_at, :desc
|
|
126
|
+
# facet :category_ids
|
|
127
|
+
# end
|
|
128
|
+
#
|
|
129
|
+
# ==== Options
|
|
130
|
+
#
|
|
131
|
+
# :include:: Specify associations to eager load
|
|
132
|
+
# :select:: Specify columns to select from database when loading results
|
|
133
|
+
#
|
|
134
|
+
# ==== Returns
|
|
135
|
+
#
|
|
136
|
+
# Sunspot::Search:: Object containing results, totals, facets, etc.
|
|
137
|
+
#
|
|
138
|
+
def solr_search(options = {}, &block)
|
|
139
|
+
solr_execute_search(options) do
|
|
140
|
+
Sunspot.new_search(self, &block)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
#
|
|
145
|
+
# Get IDs of matching results without loading the result objects from
|
|
146
|
+
# the database. This method may be useful if search is used as an
|
|
147
|
+
# intermediate step in a larger find operation. The block is the same
|
|
148
|
+
# as the block provided to the #search method.
|
|
149
|
+
#
|
|
150
|
+
# ==== Returns
|
|
151
|
+
#
|
|
152
|
+
# Array:: Array of IDs, in the order returned by the search
|
|
153
|
+
#
|
|
154
|
+
def solr_search_ids(&block)
|
|
155
|
+
solr_execute_search_ids do
|
|
156
|
+
solr_search(&block)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# Remove instances of this class from the Solr index.
|
|
162
|
+
#
|
|
163
|
+
def solr_remove_all_from_index
|
|
164
|
+
Sunspot.remove_all(self)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Remove all instances of this class from the Solr index and immediately
|
|
169
|
+
# commit.
|
|
170
|
+
#
|
|
171
|
+
#
|
|
172
|
+
def solr_remove_all_from_index!
|
|
173
|
+
Sunspot.remove_all!(self)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
#
|
|
177
|
+
# Completely rebuild the index for this class. First removes all
|
|
178
|
+
# instances from the index, then loads records and indexes them.
|
|
179
|
+
#
|
|
180
|
+
# See #index for information on options, etc.
|
|
181
|
+
#
|
|
182
|
+
def solr_reindex(options = {})
|
|
183
|
+
solr_remove_all_from_index
|
|
184
|
+
solr_index(options)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
# Add/update all existing records in the Solr index. The
|
|
189
|
+
# +batch_size+ argument specifies how many records to load out of the
|
|
190
|
+
# database at a time. The default batch size is 500; if nil is passed,
|
|
191
|
+
# records will not be indexed in batches. By default, a commit is issued
|
|
192
|
+
# after each batch; passing +false+ for +batch_commit+ will disable
|
|
193
|
+
# this, and only issue a commit at the end of the process. If associated
|
|
194
|
+
# objects need to indexed also, you can specify +include+ in format
|
|
195
|
+
# accepted by MongoMapper to improve your sql select performance
|
|
196
|
+
#
|
|
197
|
+
# ==== Options (passed as a hash)
|
|
198
|
+
#
|
|
199
|
+
# batch_size<Integer>:: Batch size with which to load records. Passing
|
|
200
|
+
# 'nil' will skip batches. Default is 500.
|
|
201
|
+
# batch_commit<Boolean>:: Flag signalling if a commit should be done after
|
|
202
|
+
# after each batch is indexed, default is 'true'
|
|
203
|
+
# include<Mixed>:: include option to be passed to the MongoMapper find,
|
|
204
|
+
# used for including associated objects that need to be
|
|
205
|
+
# indexed with the parent object, accepts all formats
|
|
206
|
+
# MongoMapper::Base.find does
|
|
207
|
+
# first_id:: The lowest possible ID for this class. Defaults to 0, which
|
|
208
|
+
# is fine for integer IDs; string primary keys will need to
|
|
209
|
+
# specify something reasonable here.
|
|
210
|
+
#
|
|
211
|
+
# ==== Examples
|
|
212
|
+
#
|
|
213
|
+
# # index in batches of 500, commit after each
|
|
214
|
+
# Post.index
|
|
215
|
+
#
|
|
216
|
+
# # index all rows at once, then commit
|
|
217
|
+
# Post.index(:batch_size => nil)
|
|
218
|
+
#
|
|
219
|
+
# # index in batches of 500, commit when all batches complete
|
|
220
|
+
# Post.index(:batch_commit => false)
|
|
221
|
+
#
|
|
222
|
+
# # include the associated +author+ object when loading to index
|
|
223
|
+
# Post.index(:include => :author)
|
|
224
|
+
#
|
|
225
|
+
def solr_index(opts={})
|
|
226
|
+
options = { :batch_size => 500, :batch_commit => true, :include => self.sunspot_options[:include], :first_id => 0}.merge(opts)
|
|
227
|
+
unless options[:batch_size]
|
|
228
|
+
Sunspot.index!(all(:include => options[:include]))
|
|
229
|
+
else
|
|
230
|
+
batch_size = options[:batch_size]
|
|
231
|
+
record_count = count
|
|
232
|
+
page = 1
|
|
233
|
+
while (page - 1) * batch_size < record_count
|
|
234
|
+
solr_benchmark options[:batch_size], page do
|
|
235
|
+
records = paginate(:page => page, :per_page => batch_size, :order => "id")
|
|
236
|
+
Sunspot.index(records)
|
|
237
|
+
end
|
|
238
|
+
Sunspot.commit if options[:batch_commit]
|
|
239
|
+
page += 1
|
|
240
|
+
end
|
|
241
|
+
Sunspot.commit unless options[:batch_commit]
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# Return the IDs of records of this class that are indexed in Solr but
|
|
247
|
+
# do not exist in the database. Under normal circumstances, this should
|
|
248
|
+
# never happen, but this method is provided in case something goes
|
|
249
|
+
# wrong. Usually you will want to rectify the situation by calling
|
|
250
|
+
# #clean_index_orphans or #reindex
|
|
251
|
+
#
|
|
252
|
+
# ==== Returns
|
|
253
|
+
#
|
|
254
|
+
# Array:: Collection of IDs that exist in Solr but not in the database
|
|
255
|
+
def solr_index_orphans
|
|
256
|
+
count = self.count
|
|
257
|
+
indexed_ids = solr_search_ids { paginate(:page => 1, :per_page => count) }.to_set
|
|
258
|
+
all(:select => 'id').each do |object|
|
|
259
|
+
indexed_ids.delete(object.id)
|
|
260
|
+
end
|
|
261
|
+
indexed_ids.to_a
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
#
|
|
265
|
+
# Find IDs of records of this class that are indexed in Solr but do not
|
|
266
|
+
# exist in the database, and remove them from Solr. Under normal
|
|
267
|
+
# circumstances, this should not be necessary; this method is provided
|
|
268
|
+
# in case something goes wrong.
|
|
269
|
+
#
|
|
270
|
+
def solr_clean_index_orphans
|
|
271
|
+
solr_index_orphans.each do |id|
|
|
272
|
+
new do |fake_instance|
|
|
273
|
+
fake_instance.id = id
|
|
274
|
+
end.solr_remove_from_index
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
#
|
|
279
|
+
# Classes that have been defined as searchable return +true+ for this
|
|
280
|
+
# method.
|
|
281
|
+
#
|
|
282
|
+
# ==== Returns
|
|
283
|
+
#
|
|
284
|
+
# +true+
|
|
285
|
+
#
|
|
286
|
+
def searchable?
|
|
287
|
+
true
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def solr_execute_search(options = {})
|
|
291
|
+
options.assert_valid_keys(:include, :select)
|
|
292
|
+
search = yield
|
|
293
|
+
unless options.empty?
|
|
294
|
+
search.build do |query|
|
|
295
|
+
if options[:include]
|
|
296
|
+
query.data_accessor_for(self).include = options[:include]
|
|
297
|
+
end
|
|
298
|
+
if options[:select]
|
|
299
|
+
query.data_accessor_for(self).select = options[:select]
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
search.execute
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def solr_execute_search_ids(options = {})
|
|
307
|
+
search = yield
|
|
308
|
+
search.raw_results.map { |raw_result| raw_result.primary_key.to_i }
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
protected
|
|
312
|
+
|
|
313
|
+
#
|
|
314
|
+
# Does some logging for benchmarking indexing performance
|
|
315
|
+
#
|
|
316
|
+
def solr_benchmark(batch_size, counter, &block)
|
|
317
|
+
start = Time.now
|
|
318
|
+
logger.info("[#{Time.now}] Start Indexing")
|
|
319
|
+
yield
|
|
320
|
+
elapsed = Time.now-start
|
|
321
|
+
logger.info("[#{Time.now}] Completed Indexing. Rows indexed #{counter * batch_size}. Rows/sec: #{batch_size/elapsed.to_f} (Elapsed: #{elapsed} sec.)")
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
module InstanceMethods
|
|
327
|
+
def self.included(base) #:nodoc:
|
|
328
|
+
base.module_eval do
|
|
329
|
+
alias_method :index, :solr_index unless method_defined? :index
|
|
330
|
+
alias_method :index!, :solr_index! unless method_defined? :index!
|
|
331
|
+
alias_method :remove_from_index, :solr_remove_from_index unless method_defined? :remove_from_index
|
|
332
|
+
alias_method :remove_from_index!, :solr_remove_from_index! unless method_defined? :remove_from_index!
|
|
333
|
+
alias_method :more_like_this, :solr_more_like_this unless method_defined? :more_like_this
|
|
334
|
+
alias_method :more_like_this_ids, :solr_more_like_this_ids unless method_defined? :more_like_this_ids
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
#
|
|
338
|
+
# Index the model in Solr. If the model is already indexed, it will be
|
|
339
|
+
# updated. Using the defaults, you will usually not need to call this
|
|
340
|
+
# method, as models are indexed automatically when they are created or
|
|
341
|
+
# updated. If you have disabled automatic indexing (see
|
|
342
|
+
# ClassMethods#searchable), this method allows you to manage indexing
|
|
343
|
+
# manually.
|
|
344
|
+
#
|
|
345
|
+
def solr_index
|
|
346
|
+
Sunspot.index(self)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
#
|
|
350
|
+
# Index the model in Solr and immediately commit. See #index
|
|
351
|
+
#
|
|
352
|
+
def solr_index!
|
|
353
|
+
Sunspot.index!(self)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
#
|
|
357
|
+
# Remove the model from the Solr index. Using the defaults, this should
|
|
358
|
+
# not be necessary, as models will automatically be removed from the
|
|
359
|
+
# index when they are destroyed. If you disable automatic removal
|
|
360
|
+
# (which is not recommended!), you can use this method to manage removal
|
|
361
|
+
# manually.
|
|
362
|
+
#
|
|
363
|
+
def solr_remove_from_index
|
|
364
|
+
Sunspot.remove(self)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
#
|
|
368
|
+
# Remove the model from the Solr index and commit immediately. See
|
|
369
|
+
# #remove_from_index
|
|
370
|
+
#
|
|
371
|
+
def solr_remove_from_index!
|
|
372
|
+
Sunspot.remove!(self)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def solr_more_like_this(*args, &block)
|
|
376
|
+
options = args.extract_options!
|
|
377
|
+
self.class.solr_execute_search(options) do
|
|
378
|
+
Sunspot.new_more_like_this(self, *args, &block)
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def solr_more_like_this_ids(&block)
|
|
383
|
+
self.class.solr_execute_search_ids do
|
|
384
|
+
solr_more_like_this(&block)
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
private
|
|
389
|
+
|
|
390
|
+
def maybe_mark_for_auto_indexing
|
|
391
|
+
@marked_for_auto_indexing =
|
|
392
|
+
if !new_record? && ignore_attributes = self.class.sunspot_options[:ignore_attribute_changes_of]
|
|
393
|
+
@marked_for_auto_indexing = !(changed.map { |attr| attr.to_sym } - ignore_attributes).blank?
|
|
394
|
+
else
|
|
395
|
+
true
|
|
396
|
+
end
|
|
397
|
+
true
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def maybe_auto_index
|
|
401
|
+
if @marked_for_auto_indexing
|
|
402
|
+
solr_index
|
|
403
|
+
remove_instance_variable(:@marked_for_auto_indexing)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'sunspot/rails/spec_helper'
|
|
2
|
+
|
|
3
|
+
Spec::Runner.configure do |config|
|
|
4
|
+
config.before(:each) do
|
|
5
|
+
::Sunspot.session = ::Sunspot::Rails::StubSessionProxy.new(::Sunspot.session)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
config.after(:each) do
|
|
9
|
+
::Sunspot.session = ::Sunspot.session.original_session
|
|
10
|
+
end
|
|
11
|
+
end
|