diff --git a/app/models/user.rb b/app/models/user.rb index 69831b6..50e058a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -8,11 +8,26 @@ class User < ActiveRecord::Base has_many :lectures has_many :workshops has_many :events + has_one :personal_profile, Proc.new { |user, conference| user.personal_profiles } default_scope { order id: :desc } - def personal_profile(conference) - personal_profiles.find_by(conference_id: conference.id) + def duplicate_last_personal_profile(conference) + if personal_profiles.any? + new_personal_profile = personal_profiles.last.dup + new_personal_profile.conference = conference + new_personal_profile + end + end + + def find_or_initialize_personal_profile(conference) + if personal_profile(conference).present? + personal_profile(conference) + elsif personal_profiles.any? + duplicate_last_personal_profile(conference) + else + personal_profiles.build(conference: conference) + end end def toggle_admin! diff --git a/config/routes.rb b/config/routes.rb index 64e9a8c..1e7a448 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,9 @@ Rails.application.routes.draw do mount OpenFest::Engine, at: '/', constraints: {subdomain: 'cfp'}, conference_id: 1 - devise_for :users, path: 'management' - namespace :management do root to: 'home#index' + devise_for :users resources :conferences do resources :events diff --git a/lib/open_fest/app/controllers/concerns/open_fest/users/devise_controller.rb b/lib/open_fest/app/controllers/concerns/open_fest/users/devise_controller.rb index f007868..0b252fd 100644 --- a/lib/open_fest/app/controllers/concerns/open_fest/users/devise_controller.rb +++ b/lib/open_fest/app/controllers/concerns/open_fest/users/devise_controller.rb @@ -5,4 +5,8 @@ module OpenFest::Users::DeviseController before_filter :require_current_conference! layout 'open_fest/application' end + + def signed_in_root_path(user) + root_path + end end diff --git a/lib/open_fest/app/controllers/open_fest/users/registrations_controller.rb b/lib/open_fest/app/controllers/open_fest/users/registrations_controller.rb index 697875e..85b97ed 100644 --- a/lib/open_fest/app/controllers/open_fest/users/registrations_controller.rb +++ b/lib/open_fest/app/controllers/open_fest/users/registrations_controller.rb @@ -1,3 +1,38 @@ class OpenFest::Users::RegistrationsController < Devise::RegistrationsController include OpenFest::Users::DeviseController + + def edit + resource.find_or_initialize_personal_profile(current_conference) + end + + def update + @user = User.find(current_user.id) + + successfully_updated = if needs_password?(@user, params) + @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) + else + # remove the virtual current_password attribute + # update_without_password doesn't know how to ignore it + params[:user].delete(:current_password) + @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) + end + + if successfully_updated + set_flash_message :notice, :updated + # Sign in the user bypassing validation in case their password changed + sign_in @user, :bypass => true + redirect_to after_update_path_for(@user) + else + render "edit" + end + end + + private + + def needs_password?(user, params) + user.email != params[:user][:email] || + params[:user][:password].present? || + params[:user][:password_confirmation].present? + end + end diff --git a/lib/open_fest/app/views/open_fest/users/registrations/edit.slim b/lib/open_fest/app/views/open_fest/users/registrations/edit.slim index 4653e82..4a654e6 100644 --- a/lib/open_fest/app/views/open_fest/users/registrations/edit.slim +++ b/lib/open_fest/app/views/open_fest/users/registrations/edit.slim @@ -1,10 +1,10 @@ - content_for(:title) { t :edit_speaker_profile } -= simple_form_for(resource, wrapper: :default, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| += simple_form_for(resource, wrapper: :default, as: resource_name, url: open_fest.user_registration_path, html: { method: :put, multipart: true }) do |f| .form_inputs h2.entry-title = t :personal_profile = f.error_notification - = f.simple_fields_for :personal_profile do |ff| + = f.simple_fields_for :personal_profile, resource.personal_profile(current_conference) do |ff| = ff.input :picture, as: :file, required: true = ff.input :first_name, autofocus: true = ff.input :last_name @@ -12,7 +12,7 @@ = ff.input :organisation = ff.input :github = ff.input :twitter - = ff.input :mobile_phone, input_html: {value: resource.personal_profile(current_conference).mobile_phone.try(:phony_formatted, format: :international)} + = ff.input :mobile_phone, input_html: {value: ff.object.mobile_phone.try(:phony_formatted, format: :international)} = ff.input :biography .form-inputs diff --git a/spec/factories/personal_profiles.rb b/spec/factories/personal_profiles.rb new file mode 100644 index 0000000..10b66e8 --- /dev/null +++ b/spec/factories/personal_profiles.rb @@ -0,0 +1,15 @@ +FactoryGirl.define do + factory :personal_profile do + first_name 'Foo' + last_name 'Bar' + organisation 'foo inc.' + public_email 'foo@example.com' + picture { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec', 'support', 'picture.jpg')) } + mobile_phone '+359883444555' + biography 'Just a bio' + github 'foobar' + twitter 'foobar' + user + conference + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9272a0f..cbae24c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -28,4 +28,39 @@ RSpec.describe User do expect(user.personal_profile(old_conference)).to eq old_profile expect(user.personal_profile(new_conference)).to eq new_profile end + + describe '#find_or_initialize_personal_profile' do + context 'when the user has a personal profile for the specified conference' do + it 'returns the existing personal profile' do + user = create :user + conference = create :conference + personal_profile = create :personal_profile, user: user, conference: conference + + expect(user.find_or_initialize_personal_profile(conference)).to eq personal_profile + end + end + + context 'when the user has a personal profile for a previous conference' do + it 'returns a duplicate of the old profile' do + user = create :user + old_conference = create :conference + conference = create :conference + personal_profile = create :personal_profile, user: user, conference: old_conference + + expect(user.find_or_initialize_personal_profile(conference).public_email).to be_present + expect(user.find_or_initialize_personal_profile(conference).public_email).to eq personal_profile.public_email + expect(user.find_or_initialize_personal_profile(conference)).to be_new_record + end + end + + context 'when the user has no personal profiles' do + it 'returns a new personal profile' do + user = create :user + conference = create :conference + + expect(user.find_or_initialize_personal_profile(conference)).to be_new_record + expect(user.find_or_initialize_personal_profile(conference).conference).to eq conference + end + end + end end