Browse files

got instrument addition working in new and edit, remove still broken

  • Loading branch information...
1 parent d361396 commit daf24ee31da5fe36b80d80421982ab037cc5e0d2 @eweiser committed Nov 12, 2012
Showing with 290 additions and 70 deletions.
  1. +4 −0 Gemfile
  2. +16 −0 Gemfile.lock
  3. +1 −0 app/assets/javascripts/application.js
  4. +4 −0 app/assets/javascripts/bootstrap.js.coffee
  5. +3 −0 app/assets/javascripts/musician.js.coffee
  6. +26 −11 app/assets/javascripts/musicians.js
  7. +31 −0 app/assets/stylesheets/bootstrap_and_overrides.css.less
  8. +3 −0 app/assets/stylesheets/musician.css.scss
  9. +5 −0 app/controllers/musician_controller.rb
  10. +60 −6 app/controllers/musicians_controller.rb
  11. +10 −4 app/controllers/omniauth_callbacks_controller.rb
  12. +16 −1 app/controllers/registrations_controller.rb
  13. +11 −9 app/helpers/musicians_helper.rb
  14. +1 −0 app/models/instrument.rb
  15. +2 −0 app/models/instrument_choice.rb
  16. +3 −2 app/models/musician.rb
  17. +2 −5 app/models/user.rb
  18. +1 −7 app/views/devise/registrations/new.html.erb
  19. +2 −2 app/views/layouts/application.html.erb
  20. +6 −0 app/views/musicians/_add_instruments.html.erb
  21. +11 −10 app/views/musicians/_form.html.erb
  22. +4 −2 app/views/musicians/_instrument_fields.html.erb
  23. +9 −0 app/views/musicians/_list_instruments.html.erb
  24. +4 −1 app/views/musicians/edit.html.erb
  25. +21 −2 app/views/musicians/new.html.erb
  26. +10 −0 app/views/musicians/show.html.erb
  27. +4 −6 config/routes.rb
  28. +0 −1 db/migrate/20121107162253_create_instrument_choices.rb
  29. +5 −0 db/migrate/20121112060432_add_unique_index_to_instrument_choices.rb
  30. +2 −1 db/schema.rb
  31. +9 −0 test/functional/musician_controller_test.rb
  32. +4 −0 test/unit/helpers/musician_helper_test.rb
View
4 Gemfile
@@ -22,6 +22,10 @@ group :assets do
# gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
+
+ gem 'therubyracer'
+ gem 'less-rails'
+ gem 'twitter-bootstrap-rails'
end
gem 'jquery-rails'
View
16 Gemfile.lock
@@ -38,6 +38,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.4.0)
+ commonjs (0.2.6)
devise (2.1.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.7)
@@ -59,6 +60,12 @@ GEM
json (1.7.5)
jwt (0.1.5)
multi_json (>= 1.0)
+ less (2.2.2)
+ commonjs (~> 0.2.6)
+ less-rails (2.2.6)
+ actionpack (>= 3.1)
+ less (~> 2.2.0)
+ libv8 (3.3.10.4)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
@@ -125,11 +132,17 @@ GEM
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
+ therubyracer (0.10.2)
+ libv8 (~> 3.3.10)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
+ twitter-bootstrap-rails (2.1.6)
+ actionpack (>= 3.1)
+ execjs
+ railties (>= 3.1)
tzinfo (0.3.34)
uglifier (1.3.0)
execjs (>= 0.3.0)
@@ -144,11 +157,14 @@ DEPENDENCIES
coffee-rails (~> 3.2.1)
devise
jquery-rails
+ less-rails
nokogiri
omniauth-facebook
pg
rails (= 3.2.5)
ransack
sass-rails (~> 3.2.3)
sqlite3
+ therubyracer
+ twitter-bootstrap-rails
uglifier (>= 1.0.3)
View
1 app/assets/javascripts/application.js
@@ -12,4 +12,5 @@
//
//= require jquery
//= require jquery_ujs
+//= require twitter/bootstrap
//= require_tree .
View
4 app/assets/javascripts/bootstrap.js.coffee
@@ -0,0 +1,4 @@
+jQuery ->
+ $("a[rel=popover]").popover()
+ $(".tooltip").tooltip()
+ $("a[rel=tooltip]").tooltip()
View
3 app/assets/javascripts/musician.js.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
View
37 app/assets/javascripts/musicians.js
@@ -1,15 +1,30 @@
-# Place all the behaviors and hooks related to the matching controller here.
+/*# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
#
-jQuery ->
- $('form').on 'click', 'remove_fields', (event) ->
- $(this).prev('input[type=hidden]').val('1')
- $(this).closest('fieldset').hide()
- event.preventDefault()
+#jQuery ->
+# $('form').on 'click', '.remove_fields', (event) ->
+# $(this).prev('input[type=hidden]').val('1')
+# $(this).closest('fieldset').hide()
+# event.preventDefault()
+#
+# $('form').on 'click', '.add_fields', (event) ->
+# time = new Date().getTime()
+# regexp = new RegExp($(this).data('id'), 'g')
+# $(this).before($(this).data('fields').replace(regexp, time))
+# event.preventDefault()*/
- $('form').on 'click', 'add_fields', (event) ->
- time = new Date().getTime()
- regexp = new RegExp($(this.).data('id'), 'g')
- $(this).before($(this).data('fields').replace(regexp, time))
- event.preventDefault()
+jQuery(function() {
+ $('form').on('click', '.remove_fields', function(event) {
+ $(this).prev('input[type=hidden]').val('1');
+ $(this).closest('fieldset').hide();
+ return event.preventDefault();
+ });
+ return $('form').on('click', '.add_fields', function(event) {
+ var regexp, time;
+ time = new Date().getTime();
+ regexp = new RegExp($(this).data('id'), 'g');
+ $(this).before($(this).data('fields').replace(regexp, time));
+ return event.preventDefault();
+ });
+});
View
31 app/assets/stylesheets/bootstrap_and_overrides.css.less
@@ -0,0 +1,31 @@
+@import "twitter/bootstrap/bootstrap";
+@import "twitter/bootstrap/responsive";
+
+// Set the correct sprite paths
+@iconSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings");
+@iconWhiteSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings-white");
+
+// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
+// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
+// have the proper paths. So for now we use the absolute path.
+@fontAwesomeEotPath: asset-path("fontawesome-webfont.eot");
+@fontAwesomeWoffPath: asset-path("fontawesome-webfont.woff");
+@fontAwesomeTtfPath: asset-path("fontawesome-webfont.ttf");
+@fontAwesomeSvgPath: asset-path("fontawesome-webfont.svg");
+
+// Font Awesome
+@import "fontawesome";
+
+// Glyphicons
+//@import "twitter/bootstrap/sprites.less";
+
+// Your custom LESS stylesheets goes here
+//
+// Since bootstrap was imported above you have access to its mixins which
+// you may use and inherit here
+//
+// If you'd like to override bootstrap's own variables, you can do so here as well
+// See http://twitter.github.com/bootstrap/customize.html#variables for their names and documentation
+//
+// Example:
+// @linkColor: #ff0000;
View
3 app/assets/stylesheets/musician.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Musician controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
View
5 app/controllers/musician_controller.rb
@@ -0,0 +1,5 @@
+
+class MusicianController < ApplicationController
+ def show
+ end
+end
View
66 app/controllers/musicians_controller.rb
@@ -12,29 +12,52 @@ def show
end
def new
- if session.has_key?(:new_user_id)
+ if session.has_key?(:new_user_id) # is user signed in after sign up?
@user = User.find(session[:new_user_id])
- session.delete(:new_user_id)
+ # keep this key for the create action to know what's good
end
+
# find existing musician accounts that might be linked to new user
- @musician_matches = Musician.where(name: user.name) unless @user.blank?
+ @musician_matches = Musician.where(name: @user.name) unless @user.blank?
if @musician_matches.blank?
@musician = Musician.new
+ @musician.instruments.build
@title = "Create musician profile"
- @instrument_options = Musician.INSTRUMENT_OPTIONS
+ render layout: false
else
@title = @musician_matches.length > 1 ? "Possible matches" : "Is this you?"
render 'match'
end
end
def create
- @musician = Musician.new(params[:musician])
+ # if profile is coming from new user creation, attach musician to user
+ if session.has_key?(:new_user_id)
+ @musician = current_user.build_musician
+ @musician.user_account = current_user
+ @musician.name = current_user.name
+ session.delete(:new_user_id)
+ else
+ @musician = Musician.new
+ @musician.name = params[:musician][:name]
+ end
+ # add musician data in piece by piece from params so we can manually add in association
+ @musician.age = params[:musician][:age]
+ @musician.bio = params[:musician][:bio]
if @musician.save
+ # load in the associations--all valid instruments have records already
+ params[:musician][:instruments_attributes].keys.each do |instrument_id| # passed as temp ids
+ instrument = Instrument.find_by_name(params[:musician][:instruments_attributes][instrument_id][:name])
+ unless @musician.instrument_choices.create(instrument_id: instrument.id)
+ @title = 'Create musician profile'
+ render 'new', layout: false
+ end
+ end
+ # sign-up successful
redirect_to @musician, flash: { success: "Profile created!"}
else
@title = "Create musician profile"
- render 'new'
+ render 'new', layout: false
end
end
@@ -43,6 +66,28 @@ def edit
@musician = Musician.find(params[:id])
end
+ def update
+ @musician = Musician.find(params[:id])
+ # add musician data in piece by piece from params so we can manually add in association
+ @musician.age = params[:musician][:age]
+ @musician.bio = params[:musician][:bio]
+ if @musician.save
+ # load in the associations--all valid instruments have records already
+ params[:musician][:instruments_attributes].keys.each do |instrument_id| # passed as temp ids
+ instrument = Instrument.find_by_name(params[:musician][:instruments_attributes][instrument_id][:name])
+ unless @musician.instrument_choices.create(instrument_id: instrument.id)
+ @title = 'Create musician profile'
+ render 'edit'
+ end
+ end
+ # sign-up successful
+ redirect_to @musician, flash: { success: "Profile created!"}
+ else
+ @title = "Create musician profile"
+ render 'edit'
+ end
+ end
+
def attach_to_user
possible_musician_profiles = Musician.where(name: user.name)
if possible_musician_profiles.blank?
@@ -53,5 +98,14 @@ def attach_to_user
end
end
+ private
+ def create_instrument_associations
+ instruments = params[:musician][:instruments_attributes].keys # list of musician's selected instruments
+ instruments.each do |instrument|
+ instrument_record = Instrument.where(name: params[:musician][:instruments_attributes][instrument][:name]).first_or_create
+ @musician.instrument_choices.new(instrument_id: instrument_record.id)
+ end
+ end
+
end
View
14 app/controllers/omniauth_callbacks_controller.rb
@@ -1,12 +1,18 @@
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
- user = User.from_omniauth(request.env["omniauth.auth"])
+ @user = User.from_omniauth(request.env["omniauth.auth"])
if false#user.persisted?
flash.notice = "Signed in!"
- sign_in_and_redirect user.musician
+ sign_in_and_redirect @user
else
- session["devise.user_attributes"] = user.attributes
- redirect_to new_user_registration_url
+ if @user.save
+ flash.notice = "Signed up!"
+ session[:new_user_id] = @user.id
+ sign_in @user
+ redirect_to new_musician_path
+ else
+ render 'user/new'
+ end
end
end
alias_method :facebook, :all
View
17 app/controllers/registrations_controller.rb
@@ -1,5 +1,20 @@
class RegistrationsController < Devise::RegistrationsController
- protected
+# def new
+# puts 'KABOOM!!'
+# if session["devise.user_attributes"]
+# puts 'KABAM!!!!!!'
+# build_resource() do |user|
+# if user.valid?
+# user.save
+# new_musician_path
+# end
+# end
+# else
+# super
+# end
+# end
+
+# protected
#def after_sign_up_path_for(resource)
# session[:new_user_id] = resource.id if resource.is_a?(User)
View
20 app/helpers/musicians_helper.rb
@@ -1,18 +1,20 @@
module MusiciansHelper
- def link_to_add_fields(name, f, association)
- new_object = f.object.send(association).klass.new
- id = new_object.object_id
- fields = f.fields_for(association, new_object, child_index: id) do |builder|
- render("instrument_fields", f: builder)
- end
- link_to("Add Instrument", '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
- end
def link_to_add_instrument(musician, f)
- new_instrument = musician.instruments.new
+ new_instrument = musician.instruments.build
id = new_instrument.object_id
fields = f.fields_for(:instruments, new_instrument, child_index: id) do |builder|
render("instrument_fields", f: builder)
end
+ link_to("Add Instrument", '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
+ end
+
+ def instrument_options
+ [["Select One", ""]] + Musician::INSTRUMENT_OPTIONS.collect{|option| [option, option]}
+ end
+ def profile_image(musician)
+ if musician.user_account
+ image_tag(musician.user_account.image)
+ end
end
end
View
1 app/models/instrument.rb
@@ -2,6 +2,7 @@ class Instrument < ActiveRecord::Base
attr_accessible :name
has_many :inverse_instrument_choices, class_name: "InstrumentChoice"
has_many :musicians, through: :inverse_instrument_choices
+ validates_uniqueness_of :name
end
View
2 app/models/instrument_choice.rb
@@ -3,4 +3,6 @@ class InstrumentChoice < ActiveRecord::Base
belongs_to :musician
belongs_to :instrument
+
+ validates_uniqueness_of :instrument_id, scope: :musician_id
end
View
5 app/models/musician.rb
@@ -1,5 +1,5 @@
class Musician < ActiveRecord::Base
- attr_accessible :age, :bio, :name, :instrument_attributes
+ attr_accessible :age, :bio, :name, :instruments_attributes
has_one :user_account, class_name: "User"
has_many :colleagueships, dependent: :destroy
has_many :colleagues, through: :colleagueships
@@ -12,8 +12,9 @@ class Musician < ActiveRecord::Base
has_many :followers, through: :reverse_follow_relationships, source: :follower
has_many :instrument_choices, foreign_key: "musician_id", dependent: :destroy
has_many :instruments, through: :instrument_choices
- accepts_nested_attributes_for :instruments, reject_if: lambda { |a| a[:content].blank? }, allow_destroy: true
+ accepts_nested_attributes_for :instruments, reject_if: lambda { |a| a[:name].blank? }, allow_destroy: true
+ validates_presence_of :name
# Instrument enum
INSTRUMENT_OPTIONS = [
"Soprano Saxophone", "Tenor Saxophone", "Alto Saxophone",
View
7 app/models/user.rb
@@ -2,7 +2,7 @@ class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
- devise :omniauthable, :rememberable
+ devise :omniauthable, :registerable, :rememberable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :first_name, :last_name, :image, :email, :remember_me
@@ -26,6 +26,7 @@ def self.from_omniauth(auth)
def self.new_with_session(params,session)
if session["devise.user_attributes"]
+ Rails.logger.info("USER_ATTRIBUTES: #{session["devise.user_attributes"]}")
new(session["devise.user_attributes"], without_protection: true) do |user|
user.attributes = params
user.valid?
@@ -35,10 +36,6 @@ def self.new_with_session(params,session)
end
end
- def password_required?
- super && provider.blank?
- end
-
def update_with_password(params, *options)
if encrypted_password.blank?
update_attributes(params, *options)
View
8 app/views/devise/registrations/new.html.erb
@@ -1,17 +1,11 @@
-<h2>Sign up</h2>
+<h2>Create your musician profile</h2>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
- <div><%= f.label :password %><br />
- <%= f.password_field :password %></div>
-
- <div><%= f.label :password_confirmation %><br />
- <%= f.password_field :password_confirmation %></div>
-
<div><%= f.submit "Sign up" %></div>
<% end %>
View
4 app/views/layouts/application.html.erb
@@ -15,8 +15,8 @@
<%if user_signed_in? %>
Logged in as <strong> <%= current_user.name %></strong>.
<%= image_tag current_user.image %>
- <%= link_to 'Edit profile', edit_user_registration_path %>
- <%= link_to 'Sign Out', user_sign_out_path %>
+ <%= link_to 'Edit profile', edit_musician_path(current_user.musician.id) %>
+ <%= link_to 'Sign Out', destroy_session_path %>
<% else %>
<%= link_to 'Sign in with Facebook', user_omniauth_authorize_path(:facebook) %>
<% end %>
View
6 app/views/musicians/_add_instruments.html.erb
@@ -0,0 +1,6 @@
+<%= f.fields_for :instruments do |builder| %>
+ <%= render 'instrument_fields', f: builder %>
+<% end %>
+<%= link_to_add_instrument @musician, f %>
+
+
View
21 app/views/musicians/_form.html.erb
@@ -1,5 +1,4 @@
-<%= form_for @musician do |f| %>
- <% if @survey.errors.any? %>
+ <% if @musician.errors.any? %>
<div class="error_messages" %>
<h2><%= pluralize(@musician.errors.count, "error") %> prohibited this survey from being saved:</h2>
<ul>
@@ -10,6 +9,13 @@
</div>
<% end %>
+ <% unless user_signed_in? %>
+ <div class="field">
+ <%= f.label :name %><br />
+ <%= f.text_field :age %>
+ </div>
+ <% end %>
+
<div class="field">
<%= f.label :age %><br />
<%= f.number_field :age %>
@@ -19,14 +25,9 @@
<%= f.label :bio %><br />
<%= f.text_area :bio %>
</div>
-
- <%= f.fields_for :instruments do |builder| %>
- <%= render 'instrument_fields', f: builder %>
- <% end %>
- <%= link_to_add_instrument @musician, f %>
+
+ <%= yield %>
<div class="action">
- <%= f.submit %>
+ <%= f.submit "Create Profile"%>
</div>
-
-<% end %>
View
6 app/views/musicians/_instrument_fields.html.erb
@@ -1,5 +1,7 @@
<fieldset>
- <%= f.select :name, options_for_select(@instrument_options) %>
+ <%= f.select :name, options_for_select(instrument_options) %>
<%= f.hidden_field :_destroy %>
- <%= link_to "remove", '#', class: "remove_fields" %>
+ <% if @musician.instruments.length > 1 %>
+ <%= link_to "remove", '#', class: "remove_fields" %>
+ <% end %>
</fieldset>
View
9 app/views/musicians/_list_instruments.html.erb
@@ -0,0 +1,9 @@
+<% @musician.instruments.each do |instrument| %>
+ <fieldset>
+ <%= instrument.name %>
+ <% if @musician.instruments.length > 1 %>
+ <%= link_to "remove", '#', class: "remove_fields" %>
+ <% end %>
+ </fieldset>
+<% end %>
+<%= link_to_add_instrument @musician, f %>
View
5 app/views/musicians/edit.html.erb
@@ -1,2 +1,5 @@
<h1><%= @musician.name %></h1>
-<%= render 'form' %>
+<%= form_for @musician do |f| %>
+ <%= render layout: 'form', partial: 'list_instruments', locals: { f: f } %>
+<% end %>
+<%= debug(params) %>
View
23 app/views/musicians/new.html.erb
@@ -1,2 +1,21 @@
-<h1>Create your musician profile</h1>
-<%= render 'form' %>
+<!DOCTYPE html>
+<html>
+<head>
+ <title>GigScape</title>
+ <%= stylesheet_link_tag "application", :media => "all" %>
+ <%= javascript_include_tag :application %>
+ <%= csrf_meta_tags %>
+</head>
+<body>
+ <p class="notice"><%= notice %></p>
+ <p class="alert"><%= alert %></p>
+
+ <h1>Welcome to GigScape, <%= current_user.first_name %>! <%= image_tag current_user.image %></h1>
+ <h2>Create your musician profile</h2>
+
+ <%= form_for @musician do |f| %>
+ <%= render layout: 'form', partial: 'add_instruments', locals: { f: f } %>
+ <% end %>
+ <%= debug(params) %>
+</body>
+</html>
View
10 app/views/musicians/show.html.erb
@@ -0,0 +1,10 @@
+<h1><%= profile_image(@musician) %> <%= @musician.name %></h1>
+<p>Age: <%= @musician.age %></p>
+<h2>BIO</h2>
+<p><%= @musician.bio %></p>
+<h2>INSTRUMENTS</h2>
+<table>
+ <% @musician.instruments.each do |instrument| %>
+ <tr><td><%=instrument.name %></td></tr>
+ <% end %>
+</table>
View
10 config/routes.rb
@@ -1,13 +1,11 @@
GigScape::Application.routes.draw do
- get "instrument_choices/create"
-
- get "instrument_choices/destroy"
-
- get "home/index"
devise_scope :user do
# Create our own sign out route point to devise's controller
- get "/user/sign_out" => "devise/sessions#destroy"
+ get "/user/sign_out" => "devise/sessions#destroy", as: :destroy_session
+
+ # Create our own sign in route point to devise's controller
+ get "/user/sign_in" => "devise/sessions#new", as: :new_session
end
devise_for :users, controllers: {
View
1 db/migrate/20121107162253_create_instrument_choices.rb
@@ -8,6 +8,5 @@ def change
end
add_index :instrument_choices, :instrument_id
add_index :instrument_choices, :musician_id
- add_index :instrument_choices, [:instrument_id, :musician_id]
end
end
View
5 db/migrate/20121112060432_add_unique_index_to_instrument_choices.rb
@@ -0,0 +1,5 @@
+class AddUniqueIndexToInstrumentChoices < ActiveRecord::Migration
+ def change
+ add_index :instrument_choices, [:instrument_id, :musician_id], unique: true
+ end
+end
View
3 db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20121107162253) do
+ActiveRecord::Schema.define(:version => 20121112060432) do
create_table "colleagueships", :force => true do |t|
t.integer "musician_id"
@@ -40,6 +40,7 @@
t.datetime "updated_at", :null => false
end
+ add_index "instrument_choices", ["instrument_id", "musician_id"], :name => "index_instrument_choices_on_instrument_id_and_musician_id", :unique => true
add_index "instrument_choices", ["instrument_id"], :name => "index_instrument_choices_on_instrument_id"
add_index "instrument_choices", ["musician_id"], :name => "index_instrument_choices_on_musician_id"
View
9 test/functional/musician_controller_test.rb
@@ -0,0 +1,9 @@
+require 'test_helper'
+
+class MusicianControllerTest < ActionController::TestCase
+ test "should get show" do
+ get :show
+ assert_response :success
+ end
+
+end
View
4 test/unit/helpers/musician_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class MusicianHelperTest < ActionView::TestCase
+end

0 comments on commit daf24ee

Please sign in to comment.