serum-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/bin/serum-rails +13 -0
- data/lib/serum/rails/app.rb +50 -0
- data/lib/serum/rails/code_scanner.rb +49 -0
- data/lib/serum/rails/metrics.rb +118 -0
- data/lib/serum/rails/type_selection.rb +31 -0
- data/lib/serum/rails/version.rb +7 -0
- data/lib/serum-rails.rb +5 -0
- data/serum-rails.gemspec +23 -0
- data/spec/serum/rails/metrics_spec.rb +87 -0
- data/spec/spec_helper.rb +80 -0
- data/spec/test_app/Capfile +4 -0
- data/spec/test_app/Gemfile +54 -0
- data/spec/test_app/Gemfile.lock +163 -0
- data/spec/test_app/Rakefile +11 -0
- data/spec/test_app/app/controllers/admin/categories_controller.rb +17 -0
- data/spec/test_app/app/controllers/admin/users_controller.rb +30 -0
- data/spec/test_app/app/controllers/application_controller/i18n_trait.rb +24 -0
- data/spec/test_app/app/controllers/application_controller/navigation_trait.rb +19 -0
- data/spec/test_app/app/controllers/application_controller/security_trait/disabled_clearance_accounts_trait.rb +41 -0
- data/spec/test_app/app/controllers/application_controller/security_trait.rb +65 -0
- data/spec/test_app/app/controllers/application_controller.rb +13 -0
- data/spec/test_app/app/controllers/conferences_controller.rb +67 -0
- data/spec/test_app/app/controllers/friendship_requests_controller.rb +31 -0
- data/spec/test_app/app/controllers/invitations_controller.rb +39 -0
- data/spec/test_app/app/controllers/members_controller.rb +21 -0
- data/spec/test_app/app/controllers/passwords_controller.rb +33 -0
- data/spec/test_app/app/controllers/sessions_controller.rb +17 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait/deletable_trait.rb +23 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait/flash_trait.rb +23 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait/helpers_trait.rb +35 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait/index_trait.rb +39 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait/log_changes_trait.rb +18 -0
- data/spec/test_app/app/controllers/shared/boring_controller_trait.rb +16 -0
- data/spec/test_app/app/controllers/users_controller.rb +49 -0
- data/spec/test_app/app/controllers/ws/api_controller/formatters_trait.rb +91 -0
- data/spec/test_app/app/controllers/ws/api_controller/parsers_trait.rb +59 -0
- data/spec/test_app/app/controllers/ws/api_controller.rb +70 -0
- data/spec/test_app/app/controllers/ws/attendees_controller.rb +43 -0
- data/spec/test_app/app/controllers/ws/categories_controller.rb +30 -0
- data/spec/test_app/app/controllers/ws/conferences_controller.rb +62 -0
- data/spec/test_app/app/controllers/ws/contacts_controller.rb +41 -0
- data/spec/test_app/app/controllers/ws/factory_controller.rb +45 -0
- data/spec/test_app/app/controllers/ws/members_controller.rb +34 -0
- data/spec/test_app/app/controllers/ws/series_controller.rb +19 -0
- data/spec/test_app/app/controllers/ws/tests_controller.rb +23 -0
- data/spec/test_app/app/helpers/application_helper.rb +180 -0
- data/spec/test_app/app/helpers/mail_helper.rb +9 -0
- data/spec/test_app/app/helpers/tags_helper.rb +16 -0
- data/spec/test_app/app/helpers/user_helper.rb +23 -0
- data/spec/test_app/app/models/attendance.rb +11 -0
- data/spec/test_app/app/models/category/ancestry_trait.rb +23 -0
- data/spec/test_app/app/models/category.rb +25 -0
- data/spec/test_app/app/models/conference/attendance_trait.rb +23 -0
- data/spec/test_app/app/models/conference/categories_trait.rb +26 -0
- data/spec/test_app/app/models/conference/icalendar_trait.rb +36 -0
- data/spec/test_app/app/models/conference/search_trait.rb +44 -0
- data/spec/test_app/app/models/conference.rb +24 -0
- data/spec/test_app/app/models/conference_category.rb +6 -0
- data/spec/test_app/app/models/conference_search.rb +51 -0
- data/spec/test_app/app/models/error.rb +25 -0
- data/spec/test_app/app/models/friendship.rb +14 -0
- data/spec/test_app/app/models/friendship_request.rb +19 -0
- data/spec/test_app/app/models/invitation.rb +38 -0
- data/spec/test_app/app/models/member_search.rb +18 -0
- data/spec/test_app/app/models/navigation.rb +38 -0
- data/spec/test_app/app/models/patterns.rb +14 -0
- data/spec/test_app/app/models/permissions.rb +106 -0
- data/spec/test_app/app/models/shared/afterlife_trait.rb +18 -0
- data/spec/test_app/app/models/shared/choice_trait.rb +37 -0
- data/spec/test_app/app/models/shared/deletable_trait.rb +8 -0
- data/spec/test_app/app/models/shared/flag_trait.rb +30 -0
- data/spec/test_app/app/models/shared/indestructible_trait.rb +19 -0
- data/spec/test_app/app/models/shared/list_field_trait.rb +70 -0
- data/spec/test_app/app/models/shared/person_name_trait.rb +25 -0
- data/spec/test_app/app/models/shared/searchable_trait.rb +71 -0
- data/spec/test_app/app/models/shared/sortable_trait.rb +24 -0
- data/spec/test_app/app/models/user/authentication_trait.rb +33 -0
- data/spec/test_app/app/models/user/authorization_trait.rb +17 -0
- data/spec/test_app/app/models/user/friends_trait.rb +42 -0
- data/spec/test_app/app/models/user/search_trait.rb +43 -0
- data/spec/test_app/app/models/user.rb +61 -0
- data/spec/test_app/app/models/util.rb +19 -0
- data/spec/test_app/app/views/admin/categories/_form.html.haml +18 -0
- data/spec/test_app/app/views/admin/categories/_list.html.haml +17 -0
- data/spec/test_app/app/views/admin/categories/edit.html.haml +6 -0
- data/spec/test_app/app/views/admin/categories/index.html.haml +6 -0
- data/spec/test_app/app/views/admin/categories/new.html.haml +6 -0
- data/spec/test_app/app/views/admin/categories/show.html.haml +27 -0
- data/spec/test_app/app/views/admin/users/_form.html.haml +49 -0
- data/spec/test_app/app/views/admin/users/_head.html.haml +5 -0
- data/spec/test_app/app/views/admin/users/_list.html.haml +20 -0
- data/spec/test_app/app/views/admin/users/_search.html.haml +9 -0
- data/spec/test_app/app/views/admin/users/deleted.html.haml +5 -0
- data/spec/test_app/app/views/admin/users/edit.html.haml +5 -0
- data/spec/test_app/app/views/admin/users/index.html.haml +7 -0
- data/spec/test_app/app/views/admin/users/new.html.haml +6 -0
- data/spec/test_app/app/views/clearance_mailer/change_password.erb +9 -0
- data/spec/test_app/app/views/conferences/_categories_list.html.haml +8 -0
- data/spec/test_app/app/views/conferences/_form.html.haml +32 -0
- data/spec/test_app/app/views/conferences/_head.html.haml +4 -0
- data/spec/test_app/app/views/conferences/_list.html.haml +22 -0
- data/spec/test_app/app/views/conferences/_search.html.haml +24 -0
- data/spec/test_app/app/views/conferences/edit.html.haml +8 -0
- data/spec/test_app/app/views/conferences/index.html.haml +22 -0
- data/spec/test_app/app/views/conferences/new.html.haml +9 -0
- data/spec/test_app/app/views/conferences/search.html.haml +7 -0
- data/spec/test_app/app/views/conferences/show.html.haml +78 -0
- data/spec/test_app/app/views/invitations/index.html.haml +26 -0
- data/spec/test_app/app/views/invitations/new.html.haml +22 -0
- data/spec/test_app/app/views/layouts/_flashes.html.haml +13 -0
- data/spec/test_app/app/views/layouts/_javascript_requirement.html.haml +8 -0
- data/spec/test_app/app/views/layouts/_javascripts.html.haml +4 -0
- data/spec/test_app/app/views/layouts/_notifications.html.haml +11 -0
- data/spec/test_app/app/views/layouts/_session_navigation.html.haml +12 -0
- data/spec/test_app/app/views/layouts/_stylesheets.html.haml +6 -0
- data/spec/test_app/app/views/layouts/screen.html.haml +30 -0
- data/spec/test_app/app/views/members/index.html.haml +40 -0
- data/spec/test_app/app/views/passwords/edit.html.haml +21 -0
- data/spec/test_app/app/views/passwords/new.html.haml +14 -0
- data/spec/test_app/app/views/sessions/new.html.haml +19 -0
- data/spec/test_app/app/views/users/_form.html.haml +45 -0
- data/spec/test_app/app/views/users/_head.html.haml +3 -0
- data/spec/test_app/app/views/users/edit.html.haml +5 -0
- data/spec/test_app/app/views/users/new.html.haml +6 -0
- data/spec/test_app/app/views/users/show.html.haml +49 -0
- data/spec/test_app/assets/data.json +981 -0
- data/spec/test_app/config/boot.rb +125 -0
- data/spec/test_app/config/cucumber.yml +8 -0
- data/spec/test_app/config/database.sample.yml +24 -0
- data/spec/test_app/config/deploy/production.rb +9 -0
- data/spec/test_app/config/deploy.rb +100 -0
- data/spec/test_app/config/environment.rb +27 -0
- data/spec/test_app/config/environments/cucumber.rb +28 -0
- data/spec/test_app/config/environments/development.rb +22 -0
- data/spec/test_app/config/environments/production.rb +35 -0
- data/spec/test_app/config/environments/test.rb +30 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/clearance.rb +5 -0
- data/spec/test_app/config/initializers/collect_hash.rb +23 -0
- data/spec/test_app/config/initializers/collection_path_with_params.rb +18 -0
- data/spec/test_app/config/initializers/cookie_verification_secret.rb +10 -0
- data/spec/test_app/config/initializers/form_builder.rb +166 -0
- data/spec/test_app/config/initializers/inflections.rb +10 -0
- data/spec/test_app/config/initializers/invert_ordered_hash.rb +12 -0
- data/spec/test_app/config/initializers/localize_textfield_input_for_numbers.rb +30 -0
- data/spec/test_app/config/initializers/mime_types.rb +7 -0
- data/spec/test_app/config/initializers/new_rails_defaults.rb +21 -0
- data/spec/test_app/config/initializers/preload_associations.rb +7 -0
- data/spec/test_app/config/initializers/query_diet.rb +6 -0
- data/spec/test_app/config/initializers/saner_field_with_errors.rb +5 -0
- data/spec/test_app/config/initializers/session_store.rb +18 -0
- data/spec/test_app/config/locales/en.yml +231 -0
- data/spec/test_app/config/preinitializer.rb +22 -0
- data/spec/test_app/config/routes.rb +47 -0
- data/spec/test_app/db/migrate/20110114164517_initial_tables.rb +52 -0
- data/spec/test_app/db/migrate/20110118090858_add_profile_fields_to_user.rb +15 -0
- data/spec/test_app/db/migrate/20110118092741_create_conference.rb +20 -0
- data/spec/test_app/db/migrate/20110118093503_create_category.rb +17 -0
- data/spec/test_app/db/migrate/20110118104438_create_conference_category.rb +16 -0
- data/spec/test_app/db/migrate/20110118105959_create_attendance.rb +17 -0
- data/spec/test_app/db/migrate/20110118122324_create_friendship_requests.rb +15 -0
- data/spec/test_app/db/migrate/20110118162436_create_invitation.rb +16 -0
- data/spec/test_app/db/migrate/20110118170347_create_friendships.rb +15 -0
- data/spec/test_app/db/migrate/20110118193528_add_timestamps_to_conference.rb +12 -0
- data/spec/test_app/db/migrate/20110119075012_set_unique_index_on_username_for_user.rb +11 -0
- data/spec/test_app/db/migrate/20110119093458_remove_first_and_last_name_from_user.rb +12 -0
- data/spec/test_app/db/migrate/20110119110857_add_missing_indexes.rb +23 -0
- data/spec/test_app/db/migrate/20110119115751_add_uniqueness_of_name_to_category.rb +9 -0
- data/spec/test_app/db/seeds.rb +5 -0
- data/spec/test_app/lib/scripts/create_many_users_sql.rb +14 -0
- data/spec/test_app/lib/tasks/cucumber.rake +53 -0
- data/spec/test_app/lib/tasks/pending_migrations.rake +24 -0
- data/spec/test_app/lib/tasks/rcov.rake +42 -0
- data/spec/test_app/lib/tasks/rspec.rake +144 -0
- data/spec/test_app/public/404.html +30 -0
- data/spec/test_app/public/422.html +30 -0
- data/spec/test_app/public/500.html +30 -0
- data/spec/test_app/public/favicon.ico +0 -0
- data/spec/test_app/public/images/ajax-loader.gif +0 -0
- data/spec/test_app/public/images/icons/balloon-quotation.png +0 -0
- data/spec/test_app/public/images/icons/balloon-sound.png +0 -0
- data/spec/test_app/public/images/icons/balloon.png +0 -0
- data/spec/test_app/public/images/icons/bell.png +0 -0
- data/spec/test_app/public/images/icons/bin.png +0 -0
- data/spec/test_app/public/images/icons/bookmark.png +0 -0
- data/spec/test_app/public/images/icons/cake.png +0 -0
- data/spec/test_app/public/images/icons/calendar-blue.png +0 -0
- data/spec/test_app/public/images/icons/calendar-month.png +0 -0
- data/spec/test_app/public/images/icons/calendar-month_light.png +0 -0
- data/spec/test_app/public/images/icons/calendar-select.png +0 -0
- data/spec/test_app/public/images/icons/card-address.png +0 -0
- data/spec/test_app/public/images/icons/cards-address.png +0 -0
- data/spec/test_app/public/images/icons/cross-script.png +0 -0
- data/spec/test_app/public/images/icons/cross-small.png +0 -0
- data/spec/test_app/public/images/icons/cross.png +0 -0
- data/spec/test_app/public/images/icons/crown-silver.png +0 -0
- data/spec/test_app/public/images/icons/crown.png +0 -0
- data/spec/test_app/public/images/icons/dashboard.png +0 -0
- data/spec/test_app/public/images/icons/document-list.png +0 -0
- data/spec/test_app/public/images/icons/document-node.png +0 -0
- data/spec/test_app/public/images/icons/document-number.png +0 -0
- data/spec/test_app/public/images/icons/document-stamp.png +0 -0
- data/spec/test_app/public/images/icons/document-task.png +0 -0
- data/spec/test_app/public/images/icons/document-text.png +0 -0
- data/spec/test_app/public/images/icons/fire.png +0 -0
- data/spec/test_app/public/images/icons/folder-medium.png +0 -0
- data/spec/test_app/public/images/icons/folder.png +0 -0
- data/spec/test_app/public/images/icons/gear.png +0 -0
- data/spec/test_app/public/images/icons/globe-green.png +0 -0
- data/spec/test_app/public/images/icons/globe-green_light.png +0 -0
- data/spec/test_app/public/images/icons/globe-medium-green.png +0 -0
- data/spec/test_app/public/images/icons/heart-break.png +0 -0
- data/spec/test_app/public/images/icons/heart.png +0 -0
- data/spec/test_app/public/images/icons/images-flickr.png +0 -0
- data/spec/test_app/public/images/icons/information-balloon.png +0 -0
- data/spec/test_app/public/images/icons/key.png +0 -0
- data/spec/test_app/public/images/icons/light-bulb.png +0 -0
- data/spec/test_app/public/images/icons/lock--exclamation.png +0 -0
- data/spec/test_app/public/images/icons/lock.png +0 -0
- data/spec/test_app/public/images/icons/magnifier-medium.png +0 -0
- data/spec/test_app/public/images/icons/magnifier.png +0 -0
- data/spec/test_app/public/images/icons/mail.png +0 -0
- data/spec/test_app/public/images/icons/paper-clip-small.png +0 -0
- data/spec/test_app/public/images/icons/paper-clip.png +0 -0
- data/spec/test_app/public/images/icons/pencil.png +0 -0
- data/spec/test_app/public/images/icons/plus-circle.png +0 -0
- data/spec/test_app/public/images/icons/plus-small.png +0 -0
- data/spec/test_app/public/images/icons/plus.png +0 -0
- data/spec/test_app/public/images/icons/printer.png +0 -0
- data/spec/test_app/public/images/icons/question-balloon.png +0 -0
- data/spec/test_app/public/images/icons/question-white.png +0 -0
- data/spec/test_app/public/images/icons/question.png +0 -0
- data/spec/test_app/public/images/icons/quill.png +0 -0
- data/spec/test_app/public/images/icons/robot.png +0 -0
- data/spec/test_app/public/images/icons/ruby_16.png +0 -0
- data/spec/test_app/public/images/icons/ruby_2_16.png +0 -0
- data/spec/test_app/public/images/icons/ruby_32.png +0 -0
- data/spec/test_app/public/images/icons/show.png +0 -0
- data/spec/test_app/public/images/icons/star.png +0 -0
- data/spec/test_app/public/images/icons/sticky-note-text.png +0 -0
- data/spec/test_app/public/images/icons/telephone-fax.png +0 -0
- data/spec/test_app/public/images/icons/telephone-fax_light.png +0 -0
- data/spec/test_app/public/images/icons/telephone.png +0 -0
- data/spec/test_app/public/images/icons/telephone_light.png +0 -0
- data/spec/test_app/public/images/icons/thumb-up.png +0 -0
- data/spec/test_app/public/images/icons/thumb.png +0 -0
- data/spec/test_app/public/images/icons/tick.png +0 -0
- data/spec/test_app/public/images/icons/trophy-silver.png +0 -0
- data/spec/test_app/public/images/icons/trophy.png +0 -0
- data/spec/test_app/public/images/icons/user-gray.png +0 -0
- data/spec/test_app/public/images/icons/user-gray_gray.png +0 -0
- data/spec/test_app/public/images/icons/user-medium.png +0 -0
- data/spec/test_app/public/images/icons/user-red.png +0 -0
- data/spec/test_app/public/images/icons/users.png +0 -0
- data/spec/test_app/public/images/icons/users_gray.png +0 -0
- data/spec/test_app/public/images/icons/xfn.png +0 -0
- data/spec/test_app/public/images/legend_bg.png +0 -0
- data/spec/test_app/public/images/poshytip/tip-deepgray.png +0 -0
- data/spec/test_app/public/images/poshytip/tip-deepgray_arrows.png +0 -0
- data/spec/test_app/public/images/stripes_bottom_dark.png +0 -0
- data/spec/test_app/public/images/stripes_top_dark.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_flat_10_000000_40x100.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/spec/test_app/public/images/ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/spec/test_app/public/images/ui/ui-icons_222222_256x240.png +0 -0
- data/spec/test_app/public/images/ui/ui-icons_228ef1_256x240.png +0 -0
- data/spec/test_app/public/images/ui/ui-icons_ef8c08_256x240.png +0 -0
- data/spec/test_app/public/images/ui/ui-icons_ffd27a_256x240.png +0 -0
- data/spec/test_app/public/images/ui/ui-icons_ffffff_256x240.png +0 -0
- data/spec/test_app/public/javascripts/application.js +175 -0
- data/spec/test_app/public/javascripts/lib/jquery-1.4.2.min.js +154 -0
- data/spec/test_app/public/javascripts/lib/jquery-ui-1.8.5.custom.min.js +249 -0
- data/spec/test_app/public/javascripts/lib/jquery-ui-1.8.5.custom.min.txt +9 -0
- data/spec/test_app/public/javascripts/lib/jquery-ui-timepicker-addon.js +682 -0
- data/spec/test_app/public/javascripts/lib/jquery-ui-timepicker-addon.min.js +22 -0
- data/spec/test_app/public/javascripts/lib/jquery.elastic.js +6 -0
- data/spec/test_app/public/javascripts/lib/jquery.elastic.performance.js +128 -0
- data/spec/test_app/public/javascripts/lib/jquery.elastic.source.js +117 -0
- data/spec/test_app/public/javascripts/lib/jquery.poshytip.js +414 -0
- data/spec/test_app/public/javascripts/lib/jquery.poshytip.min.js +7 -0
- data/spec/test_app/public/javascripts/lib/jquery.ui.datepicker-de.js +23 -0
- data/spec/test_app/public/javascripts/lib/jrails.js +1 -0
- data/spec/test_app/public/javascripts/lib/multiple-autocomplete.js +39 -0
- data/spec/test_app/public/javascripts/lib/underscore-min.js +17 -0
- data/spec/test_app/public/javascripts/lib/underscore.js +704 -0
- data/spec/test_app/public/robots.txt +5 -0
- data/spec/test_app/public/stylesheets/lib/PIE.htc +77 -0
- data/spec/test_app/public/stylesheets/lib/PIE_uncompressed.htc +3064 -0
- data/spec/test_app/public/stylesheets/lib/jquery-ui-timepicker-addon.css +11 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray.css +62 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray_arrows.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-deepgray/tip-deepgray.css +64 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-green/tip-green.css +57 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-green/tip-green_arrows.gif +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue.css +58 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue_arrows.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-twitter/tip-twitter.css +59 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-twitter/tip-twitter_arrows.gif +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet.css +60 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet_arrows.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow.css +60 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow_arrows.png +0 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellowsimple/tip-yellowsimple.css +60 -0
- data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellowsimple/tip-yellowsimple_arrows.gif +0 -0
- data/spec/test_app/public/stylesheets/lib/ui-lightness/jquery-ui-1.8.5.custom.css +459 -0
- data/spec/test_app/public/stylesheets/sass/_mixins.sass +79 -0
- data/spec/test_app/public/stylesheets/sass/_reset.sass +40 -0
- data/spec/test_app/public/stylesheets/sass/print.sass +22 -0
- data/spec/test_app/public/stylesheets/sass/screen.sass +866 -0
- data/spec/test_app/script/about +4 -0
- data/spec/test_app/script/autospec +6 -0
- data/spec/test_app/script/console +3 -0
- data/spec/test_app/script/cucumber +10 -0
- data/spec/test_app/script/dbconsole +3 -0
- data/spec/test_app/script/destroy +3 -0
- data/spec/test_app/script/generate +3 -0
- data/spec/test_app/script/performance/benchmarker +3 -0
- data/spec/test_app/script/performance/profiler +3 -0
- data/spec/test_app/script/plugin +3 -0
- data/spec/test_app/script/runner +3 -0
- data/spec/test_app/script/server +3 -0
- data/spec/test_app/script/spec +10 -0
- metadata +748 -0
@@ -0,0 +1,180 @@
|
|
1
|
+
# Methods added to this helper will be available to all templates in the application.
|
2
|
+
# origin: RM
|
3
|
+
module ApplicationHelper
|
4
|
+
|
5
|
+
def icon(icon, label)
|
6
|
+
content_tag(:span, label, :class => "#{icon}_icon")
|
7
|
+
end
|
8
|
+
|
9
|
+
def page_head(options = {})
|
10
|
+
html = ''.html_safe
|
11
|
+
html << content_tag(:h1, options[:title]) if options[:title]
|
12
|
+
html << render_navigation(options[:navigation]) if options[:navigation]
|
13
|
+
if html.present?
|
14
|
+
content_for(:page_head) do
|
15
|
+
content_tag(:div, :id => 'page_head') do
|
16
|
+
content_tag(:div, :id => 'page_head_inner') do
|
17
|
+
html
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def page_navigation(navigation)
|
25
|
+
content_for(:page_navigation, render_navigation(navigation, :id => 'page_navigation'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def uid
|
29
|
+
@@next_uid ||= 0
|
30
|
+
@@next_uid += 1
|
31
|
+
"element_uid_#{@@next_uid}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# This method is supposed to work with Tex output. Don't use HTML entities.
|
35
|
+
def money_amount(amount)
|
36
|
+
if amount.present?
|
37
|
+
"#{amount.with_comma(2)} €" # this includes a nbsp!
|
38
|
+
else
|
39
|
+
"–" # ‐
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def maybe_blank(value, options = {})
|
44
|
+
if value.present?
|
45
|
+
if options[:url] && Patterns::URL.match(value)
|
46
|
+
link_to(value, value)
|
47
|
+
elsif options[:simple_format]
|
48
|
+
simple_format(value)
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
else
|
53
|
+
'–'.html_safe
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def body_id(id)
|
58
|
+
content_for :body_id, id
|
59
|
+
end
|
60
|
+
|
61
|
+
def help(message)
|
62
|
+
content_tag :span, "(#{h message})".html_safe, :class => 'help'
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear
|
66
|
+
content_tag :div, '', :class => 'clear'
|
67
|
+
end
|
68
|
+
|
69
|
+
def todo(message)
|
70
|
+
content_tag :span, h(message), :class => 'todo'
|
71
|
+
end
|
72
|
+
|
73
|
+
def pagination(collection)
|
74
|
+
will_paginate collection, :previous_label => "« zurück", :next_label => "weiter »"
|
75
|
+
end
|
76
|
+
|
77
|
+
def buttons(options = {}, &block)
|
78
|
+
content = capture(&block)
|
79
|
+
if content.present?
|
80
|
+
content += content_tag(:div, options[:links], :class => 'links') if options[:links]
|
81
|
+
html = content_tag :div, content.html_safe, :class => "buttons #{options[:class]}"
|
82
|
+
block_called_from_erb?(block) ? concat(html) : html
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def save_cancel_buttons(options = {})
|
87
|
+
cancel_path = options.delete(:cancel_path) || root_path
|
88
|
+
save_label = options.delete(:save_label) || "Save"
|
89
|
+
cancel_label = options.delete(:cancel_label) || "Cancel"
|
90
|
+
buttons(options.reverse_merge(:class => 'bar')) do
|
91
|
+
html = ''
|
92
|
+
html << submit_tag(save_label, :class => "submit", :disable_with => "Please wait...")
|
93
|
+
html << button_to_function(cancel_label, "location.href = '#{cancel_path}'")
|
94
|
+
html
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def boring_create_button(options = {}, &block)
|
99
|
+
button = link_to(icon(:create, options[:label] || "Add"), new_object_path)
|
100
|
+
buttons(&prepend_html_to_block(button, block))
|
101
|
+
end
|
102
|
+
|
103
|
+
def boring_delete_button(options = {}, &block)
|
104
|
+
link_to(icon(:delete, "Delete"), object_url, :method => :delete)
|
105
|
+
end
|
106
|
+
|
107
|
+
def boring_edit_button(options = {}, &block)
|
108
|
+
link_to(icon(:edit, "Edit"), edit_object_url)
|
109
|
+
end
|
110
|
+
|
111
|
+
def prepend_html_to_block(html, block)
|
112
|
+
lambda do
|
113
|
+
concatenated = ''.html_safe
|
114
|
+
concatenated << html
|
115
|
+
concatenated << capture(&block) if block
|
116
|
+
concatenated
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def boring_save_cancel_buttons(options = {})
|
121
|
+
target = translate_model_name(object)
|
122
|
+
deleted = object.respond_to?(:deleted?) && object.deleted?
|
123
|
+
links = options.delete(:links)
|
124
|
+
cancel_path = options.delete(:cancel_path) || collection_path
|
125
|
+
action = deleted ? "restore" : "delete"
|
126
|
+
delete_link = if options[:delete_link] && !object.new_record?
|
127
|
+
link_class = deleted ? "restore" : "delete"
|
128
|
+
label = icon(link_class, action.titleize)
|
129
|
+
confirm = options[:"confirm_#{link_class}"] || "#{action.titleize} this #{target}?"
|
130
|
+
confirm = confirm.call if confirm.respond_to?(:call)
|
131
|
+
link_to(label, object_url(object), :method => :delete, :confirm => confirm)
|
132
|
+
else
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
save_cancel_buttons options.merge(
|
136
|
+
:links => "#{links} #{delete_link}".html_safe,
|
137
|
+
:cancel_path => cancel_path
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
def list
|
142
|
+
content_tag(:div, render('list'), :id => 'list')
|
143
|
+
end
|
144
|
+
|
145
|
+
def columns(&content)
|
146
|
+
concat(
|
147
|
+
content_tag(:div, capture(&content) + clear, :class => 'columns')
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
def column(options = {}, &content)
|
152
|
+
size_class = [options[:size], 'column'].compact.join('_')
|
153
|
+
klass = [size_class, options[:class]].join(' ')
|
154
|
+
content = capture(&content)
|
155
|
+
content = segment(:title => options[:segment], :content => content) if options[:segment]
|
156
|
+
html = content_tag(:div, :class => klass) do
|
157
|
+
content_tag(:div, content, :class => 'column_inner')
|
158
|
+
end
|
159
|
+
concat html
|
160
|
+
end
|
161
|
+
|
162
|
+
def segment(options = {}, &block)
|
163
|
+
title = options[:title]
|
164
|
+
html = ''
|
165
|
+
html << "<div class='segment #{options[:class]}' id='#{options[:id]}' data-show-for='#{options[:"data-show-for"]}'>"
|
166
|
+
html << "<h3 class=\"segment_title\"><span>#{title}</span></h3>" if title.present?
|
167
|
+
html << '<div class="segment_body">'
|
168
|
+
html << (options[:content] || capture(&block))
|
169
|
+
html << '</div>'
|
170
|
+
html << "</div>"
|
171
|
+
html = html.html_safe
|
172
|
+
block && block_called_from_erb?(block) ? concat(html) : html
|
173
|
+
end
|
174
|
+
|
175
|
+
def graceful_link_to_remote(name, options = {}, html_options = nil)
|
176
|
+
html_options ||= {}
|
177
|
+
link_to_remote(name, options, html_options.merge(:href => options[:url], :method => options[:method]))
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Helper for displaying tag clouds (not used in CaP).
|
2
|
+
# origin: RM
|
3
|
+
module TagsHelper
|
4
|
+
|
5
|
+
def render_tags(tags)
|
6
|
+
tags = tags.collect do |tag|
|
7
|
+
tag.respond_to?(:name) ? tag.name : tag
|
8
|
+
end
|
9
|
+
content_tag :div, :class => 'tags' do
|
10
|
+
tags.sort_by { |t| t.downcase }.collect do |tag|
|
11
|
+
content_tag :span, h(tag), :class => 'tag'
|
12
|
+
end.join(' ').html_safe
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Helper methods that deal with the display of user information.
|
2
|
+
# origin: M
|
3
|
+
module UserHelper
|
4
|
+
|
5
|
+
def friendship_status(user, only_image = false)
|
6
|
+
icon, title = if current_user == user
|
7
|
+
[ 'icons/user-red.png', 'This is you' ]
|
8
|
+
elsif current_user.friends_with?(user)
|
9
|
+
[ 'icons/user-medium.png', 'Confirmed contact' ]
|
10
|
+
elsif current_user.in_contact_with?(user)
|
11
|
+
[ 'icons/mail.png', 'Contact request sent' ]
|
12
|
+
else
|
13
|
+
[ 'icons/user-gray_gray.png', 'No confirmed contact' ]
|
14
|
+
end
|
15
|
+
|
16
|
+
if only_image
|
17
|
+
image_tag icon, :title => title, :alt => title
|
18
|
+
else
|
19
|
+
content_tag :div, title, :class => 'friend_status', :style => "background-image: url(#{image_path icon})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Stores the fact that a user is attending a conference.
|
2
|
+
# origin: M
|
3
|
+
class Attendance < ActiveRecord::Base
|
4
|
+
|
5
|
+
validates_presence_of :user_id, :conference_id
|
6
|
+
validates_uniqueness_of :user_id, :scope => :conference_id
|
7
|
+
|
8
|
+
belongs_to :user
|
9
|
+
belongs_to :conference
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Provides category hierarchies.
|
2
|
+
# origin: RM
|
3
|
+
module Category::AncestryTrait
|
4
|
+
as_trait do
|
5
|
+
|
6
|
+
has_ancestry
|
7
|
+
|
8
|
+
belongs_to :mother, :class_name => 'Category'
|
9
|
+
before_validation :sync_mother_and_parent_id
|
10
|
+
|
11
|
+
# This method serves two purposes:
|
12
|
+
# 1. Cache ancestry's virtual parent_id in a real database column because that makes some queries easier
|
13
|
+
# 2. Allow to set parent_id by setting mother_id so code that uses association reflection works
|
14
|
+
def sync_mother_and_parent_id
|
15
|
+
if mother_id_changed?
|
16
|
+
self.parent_id = mother_id
|
17
|
+
else
|
18
|
+
self.mother_id = parent_id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# A single conference category.
|
2
|
+
# origin: M
|
3
|
+
class Category < ActiveRecord::Base
|
4
|
+
|
5
|
+
does 'category/ancestry'
|
6
|
+
does 'sortable', :by => :name
|
7
|
+
does 'indestructible'
|
8
|
+
|
9
|
+
validates_presence_of :name
|
10
|
+
validates_uniqueness_of :name
|
11
|
+
|
12
|
+
named_scope :by_name, :order => :name
|
13
|
+
|
14
|
+
def conferences
|
15
|
+
category_ids = (descendants.collect(&:id) + [id]).uniq
|
16
|
+
Conference.in_categories(category_ids)
|
17
|
+
end
|
18
|
+
|
19
|
+
def available_parents
|
20
|
+
(Category.all - [self]).sort.collect do |category|
|
21
|
+
[category.name, category.id]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Trait to manage the attendees of a conference.
|
2
|
+
# origin: M
|
3
|
+
module Conference::AttendanceTrait
|
4
|
+
as_trait do
|
5
|
+
|
6
|
+
has_many :attendances, :dependent => :destroy
|
7
|
+
has_many :attendees, :through => :attendances, :source => :user
|
8
|
+
|
9
|
+
def attended_by?(user)
|
10
|
+
@attendee_ids ||= attendee_ids
|
11
|
+
@attendee_ids.include?(user.id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def attend!(user)
|
15
|
+
attendees << user unless attended_by?(user)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cancel_attendance!(user)
|
19
|
+
attendees.delete(user) if attended_by?(user)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Trait to manage the categories of a conference.
|
2
|
+
# origin: M
|
3
|
+
module Conference::CategoriesTrait
|
4
|
+
|
5
|
+
as_trait do
|
6
|
+
|
7
|
+
has_many :conference_categories
|
8
|
+
has_many :categories, :through => :conference_categories
|
9
|
+
|
10
|
+
does 'list_field', :category_list
|
11
|
+
|
12
|
+
def category_names
|
13
|
+
categories.collect(&:name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def read_category_list
|
17
|
+
category_ids.collect(&:to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def write_category_list(ids)
|
21
|
+
self.category_ids = ids.collect(&:to_i)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'vpim/icalendar'
|
2
|
+
|
3
|
+
# Trait to export a conference in iCalendar format.
|
4
|
+
# origin: M
|
5
|
+
module Conference::IcalendarTrait
|
6
|
+
as_trait do
|
7
|
+
|
8
|
+
def to_icalendar(viewing_user)
|
9
|
+
Vpim::Icalendar.create2.tap do |calendar|
|
10
|
+
calendar.add_event do |e|
|
11
|
+
e.dtstart start_date
|
12
|
+
e.dtend(end_date + 1.day)
|
13
|
+
e.summary name
|
14
|
+
e.description description
|
15
|
+
e.categories category_names
|
16
|
+
e.organizer visible_vcard_address(user, :for => viewing_user)
|
17
|
+
for attendee in attendees
|
18
|
+
e.add_attendee visible_vcard_address(attendee, :for => viewing_user)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def visible_vcard_address(user, options)
|
27
|
+
viewing_user = options[:for]
|
28
|
+
force_visible = (user == self.user)
|
29
|
+
Vpim::Icalendar::Address.new.tap do |address|
|
30
|
+
address.cn = viewing_user.name_for(user, force_visible)
|
31
|
+
address.uri = viewing_user.sees_details_of?(user, force_visible) ? "mailto:#{user.email}" : NO_REPLY_EMAIL
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Trait to provide search functionality for conferences.
|
2
|
+
# origin: M
|
3
|
+
module Conference::SearchTrait
|
4
|
+
|
5
|
+
as_trait do
|
6
|
+
|
7
|
+
does 'searchable', :text_means => 'query'
|
8
|
+
|
9
|
+
named_scope :in_categories, lambda { |ids| { :conditions => ['conference_categories.category_id IN (?)', ids], :joins => :conference_categories, :group => 'conferences.id' } }
|
10
|
+
|
11
|
+
named_scope :from_date, lambda { |date| { :conditions => ['conferences.end_date >= ?', date] } }
|
12
|
+
named_scope :until_date, lambda { |date| { :conditions => ['conferences.start_date <= ?', date] } }
|
13
|
+
|
14
|
+
search_by :query do |query|
|
15
|
+
scoped :conditions => Util.like_query('CONCAT_WS(" ", conferences.name, conferences.description)', query)
|
16
|
+
end
|
17
|
+
|
18
|
+
search_by :from do |date_string|
|
19
|
+
date = Date.parse(date_string) rescue nil
|
20
|
+
if date
|
21
|
+
from_date(date)
|
22
|
+
else
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
search_by :until do |date_string|
|
28
|
+
date = Date.parse(date_string) rescue nil
|
29
|
+
if date
|
30
|
+
until_date(date)
|
31
|
+
else
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
search_by :cat do |category_string|
|
37
|
+
category_id = Category.find_by_name(category_string).andand.id
|
38
|
+
in_categories([category_id])
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Models a conference.
|
2
|
+
# origin: M
|
3
|
+
class Conference < ActiveRecord::Base
|
4
|
+
does 'conference/categories'
|
5
|
+
does 'conference/attendance'
|
6
|
+
does 'conference/icalendar'
|
7
|
+
does 'conference/search'
|
8
|
+
|
9
|
+
belongs_to :user
|
10
|
+
|
11
|
+
validates_presence_of :name, :start_date, :end_date, :description, :address, :user_id
|
12
|
+
|
13
|
+
named_scope :by_name, :order => :name
|
14
|
+
named_scope :running, lambda {{ :conditions => ['start_date <= ? AND ? <= end_date', Date.today, Date.today] }}
|
15
|
+
|
16
|
+
has_attachment :logo
|
17
|
+
|
18
|
+
validate do |record|
|
19
|
+
if record.start_date and record.end_date and record.start_date > record.end_date
|
20
|
+
record.errors.add :end_date, 'must be after the start date'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Maps the conference search form to scopes provided by the conference model.
|
2
|
+
# origin: M
|
3
|
+
class ConferenceSearch
|
4
|
+
|
5
|
+
attr_accessor :query, :category_ids, :from, :until
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@query = options[:query]
|
9
|
+
@category_ids = options[:category_ids] || []
|
10
|
+
@until = options[:until]
|
11
|
+
@from = options[:from]
|
12
|
+
end
|
13
|
+
|
14
|
+
def find
|
15
|
+
scope = Conference
|
16
|
+
if query
|
17
|
+
scope = scope.search(query)
|
18
|
+
end
|
19
|
+
if category_ids.present?
|
20
|
+
scope = scope.in_categories(category_ids)
|
21
|
+
end
|
22
|
+
if from_date
|
23
|
+
scope = scope.from_date(from_date)
|
24
|
+
elsif !until_date and (query.blank? or (!query.include?('from:') and !query.include?('to:')))
|
25
|
+
scope = scope.from_date(Date.today)
|
26
|
+
end
|
27
|
+
if until_date
|
28
|
+
scope = scope.until_date(until_date)
|
29
|
+
end
|
30
|
+
scope
|
31
|
+
end
|
32
|
+
|
33
|
+
# Define this method to silence deprecation warnings when we are using the non-ActiveRecord class in Rails forms.
|
34
|
+
def id
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def until_date
|
39
|
+
Date.parse(@until) rescue nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def from_date
|
43
|
+
Date.parse(@from) rescue nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def present?
|
47
|
+
query.present? or from_date.present? or until_date.present? or category_ids.present?
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Utility class to extract validation errors from ActiveRecord models in a readable fashion.
|
2
|
+
# origin: RM
|
3
|
+
class Error
|
4
|
+
|
5
|
+
def self.messages(object, options = {})
|
6
|
+
except = Set.new(options.delete(:except) || [])
|
7
|
+
object.errors.collect do |attribute, _|
|
8
|
+
message(object, attribute) unless except.include? attribute
|
9
|
+
end.compact
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.message(object, attribute)
|
13
|
+
message = Array(object.errors.on(attribute))
|
14
|
+
if message.present?
|
15
|
+
message = message.first
|
16
|
+
if message.starts_with?('^')
|
17
|
+
message[1..-1]
|
18
|
+
else
|
19
|
+
translated_attribute = I18n.t("activerecord.attributes.#{object.class.name.underscore}.#{attribute}")
|
20
|
+
"#{translated_attribute} #{message}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Stores the fact that a user is the confirmed friend of another user.
|
2
|
+
# origin: M
|
3
|
+
class Friendship < ActiveRecord::Base
|
4
|
+
|
5
|
+
belongs_to :user
|
6
|
+
belongs_to :friend, :class_name => 'User'
|
7
|
+
|
8
|
+
validates_presence_of :user_id, :friend_id
|
9
|
+
|
10
|
+
def self.import(path)
|
11
|
+
YAML.load(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Stores the fact that a user has requested to be the friend of another user.
|
2
|
+
# origin: M
|
3
|
+
class FriendshipRequest < ActiveRecord::Base
|
4
|
+
|
5
|
+
belongs_to :user
|
6
|
+
belongs_to :requesting_user, :class_name => 'User'
|
7
|
+
|
8
|
+
validates_presence_of :user_id, :requesting_user_id
|
9
|
+
|
10
|
+
# When a friendship request is accepted, two Friendship records are created (one for each direction).
|
11
|
+
def accept
|
12
|
+
user.friendships.create(:friend => requesting_user) and requesting_user.friendships.create(:friend => user) and destroy
|
13
|
+
end
|
14
|
+
|
15
|
+
def deny
|
16
|
+
destroy
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Stores the fact that a user has invited one of her friends to attend a conference.
|
2
|
+
# origin: M
|
3
|
+
class Invitation < ActiveRecord::Base
|
4
|
+
|
5
|
+
belongs_to :recipient, :class_name => 'User'
|
6
|
+
belongs_to :sender, :class_name => 'User'
|
7
|
+
belongs_to :conference
|
8
|
+
|
9
|
+
validates_presence_of :conference_id, :recipient_id, :sender_id
|
10
|
+
|
11
|
+
validate :recipient_must_be_a_friend
|
12
|
+
|
13
|
+
named_scope :for_recipient, lambda { |recipient| { :conditions => { :recipient_id => recipient.id }}}
|
14
|
+
named_scope :include_everything, :include => [:recipient, :sender, :conference]
|
15
|
+
|
16
|
+
def accept!
|
17
|
+
conference.attend!(recipient)
|
18
|
+
destroy
|
19
|
+
end
|
20
|
+
|
21
|
+
def dismiss!
|
22
|
+
destroy
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def recipient_must_be_a_friend
|
28
|
+
if sender && recipient && !sender.friends.include?(recipient)
|
29
|
+
errors.add(:recipient_id, 'is not a confirmed contact of the invitation sender')
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.import(path)
|
35
|
+
YAML.load(path)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Maps the member search form to the scopes provided by the user model.
|
2
|
+
# origin: M
|
3
|
+
class MemberSearch
|
4
|
+
|
5
|
+
attr_reader :users, :name
|
6
|
+
|
7
|
+
def initialize(user, options = nil)
|
8
|
+
options ||= {} # When using params from the controller without any search query, nil will be passed. Thus, assigning a default value here.
|
9
|
+
@users = User.active
|
10
|
+
@users = @users.search(options[:name], user) if options[:name].present?
|
11
|
+
end
|
12
|
+
|
13
|
+
# Define this method to silence deprecation warnings when we are using the non-ActiveRecord class in Rails forms.
|
14
|
+
def id
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Describes the navigation used by the application views.
|
2
|
+
# Controllers can map their actions into symbols defined by this class.
|
3
|
+
# origin: RM
|
4
|
+
class Navigation < SimpleNavigation
|
5
|
+
|
6
|
+
navigation :main do
|
7
|
+
section :conferences, :label => 'Conferences', :url => lambda { conferences_path } do
|
8
|
+
section :browse, :label => 'Browse', :url => lambda { conferences_path }
|
9
|
+
section :search, :label => 'Search', :url => lambda { search_conferences_path }
|
10
|
+
section :invitations, :label => 'Invitations', :url => lambda { invitations_path }, :show => lambda { current_user.may_index_invitations? }
|
11
|
+
end
|
12
|
+
section :members, :label => 'Members', :url => lambda { members_path }, :show => lambda { current_user.may_index_members? } do
|
13
|
+
section :member_search, :label => 'Search', :url => lambda { members_path }
|
14
|
+
section :profile, :label => 'My profile', :url => lambda { user_path(current_user) }, :show => lambda { current_user.may_access_own_profile? }
|
15
|
+
end
|
16
|
+
section :admin_users, :label => 'Admin users', :url => lambda { admin_users_path }, :show => lambda { current_user.may_index_admin_users? } do
|
17
|
+
section :active_users, :label => 'Active users', :url => lambda { admin_users_path }
|
18
|
+
section :deleted_users, :label => 'Deleted users', :url => lambda { deleted_admin_users_path }
|
19
|
+
end
|
20
|
+
section :admin_categories, :label => 'Admin categories', :url => lambda { admin_categories_path }, :show => lambda { current_user.may_index_admin_categories? }
|
21
|
+
end
|
22
|
+
|
23
|
+
navigation :admin_category do
|
24
|
+
section :show, :label => lambda { icon(:show, 'Overview') }, :url => lambda { object_path }
|
25
|
+
section :edit, :label => lambda { icon(:edit, 'Edit') }, :url => lambda { edit_object_path }
|
26
|
+
end
|
27
|
+
|
28
|
+
navigation :conference do
|
29
|
+
section :show, :label => lambda { icon(:show, 'Overview') }, :url => lambda { object_path }
|
30
|
+
section :edit, :label => lambda { icon(:edit, 'Edit') }, :url => lambda { edit_object_path }, :show => lambda { current_user.may_update_conference?(object) }
|
31
|
+
end
|
32
|
+
|
33
|
+
navigation :user do
|
34
|
+
section :show, :label => lambda { icon(:show, 'Overview') }, :url => lambda { object_path }
|
35
|
+
section :edit, :label => lambda { icon(:edit, 'Edit') }, :url => lambda { edit_object_path }, :show => lambda { current_user.may_update_user?(object) }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|