Refactoring lodgings
This commit is contained in:
parent
c0cdf3e6e5
commit
580c6c6ed9
11 changed files with 177 additions and 68 deletions
|
|
@ -2,7 +2,7 @@ module Admin
|
||||||
class LodgingsController < Admin::BaseController
|
class LodgingsController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource :venue, through: :conference, singleton: true
|
load_and_authorize_resource :venue, through: :conference, singleton: true
|
||||||
authorize_resource :lodging, through: :venue
|
load_and_authorize_resource :lodging, through: :venue
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize! :update, Lodging.new(venue_id: @venue.id)
|
authorize! :update, Lodging.new(venue_id: @venue.id)
|
||||||
|
|
@ -10,14 +10,48 @@ module Admin
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@lodging = @venue.lodgings.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@lodging = @venue.lodgings.new(lodging_params)
|
||||||
|
if @lodging.save
|
||||||
|
redirect_to(admin_conference_lodging_path(conference_id: @conference.short_title, id: @lodging.id),
|
||||||
|
notice: 'Lodging successfully created.')
|
||||||
|
else
|
||||||
|
flash[:error] = "Creating Lodging failed: #{@lodging.errors.full_messages.join('. ')}."
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @venue.update_attributes(params[:venue])
|
if @lodging.update_attributes(lodging_params)
|
||||||
|
redirect_to(admin_conference_lodging_path(conference_id: @conference.short_title, id: @lodging.id),
|
||||||
|
notice: 'Lodging successfully updated.')
|
||||||
|
else
|
||||||
|
flash[:error] = "Update Lodging failed: #{@lodging.errors.full_messages.join('. ')}."
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @lodging.destroy
|
||||||
redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title),
|
redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title),
|
||||||
notice: 'Lodgings were successfully updated.')
|
notice: 'Lodging successfully deleted.')
|
||||||
else
|
else
|
||||||
redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title),
|
redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title),
|
||||||
notice: 'Updating lodgings failed!')
|
error: 'Deleting lodging failed.' \
|
||||||
|
"#{@lodging.errors.full_messages.join('. ')}.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def lodging_params
|
||||||
|
params[:lodging]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
class Lodging < ActiveRecord::Base
|
class Lodging < ActiveRecord::Base
|
||||||
attr_accessible :name, :description, :photo, :website_link, :venue_id
|
attr_accessible :name, :description, :photo, :website_link, :venue_id
|
||||||
belongs_to :venue
|
belongs_to :venue
|
||||||
|
|
||||||
|
validates :name, presence: true
|
||||||
|
|
||||||
has_attached_file :photo,
|
has_attached_file :photo,
|
||||||
styles: { thumb: '100x100>', large: '300x300>' }
|
styles: { thumb: '100x100>', large: '300x300>' }
|
||||||
|
|
||||||
|
|
|
||||||
8
app/views/admin/lodgings/_form.html.haml
Normal file
8
app/views/admin/lodgings/_form.html.haml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
= f.input :name
|
||||||
|
= f.input :description, :input_html => {:rows => 2, data: { provide: "markdown-editable" } }, hint: markdown_hint("Write about the hotel/place, of what they are offering, about types of rooms, prices and address.")
|
||||||
|
= image_tag f.object.photo(:thumb) if !f.object.photo.blank?
|
||||||
|
= f.input :photo
|
||||||
|
= f.input :website_link
|
||||||
|
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||||
|
|
||||||
|
= link_to 'Back', admin_conference_lodgings_path(@conference.short_title)
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<div class="nested-fields">
|
|
||||||
<%= f.inputs do %>
|
|
||||||
<%= f.input :name %>
|
|
||||||
<%= f.input :description, :input_html => {:rows => 2, data: { provide: "markdown-editable" } }, hint: markdown_hint("Write about the hotel/place, of what they are offering, about types of rooms, prices and address.") %>
|
|
||||||
<%= image_tag f.object.photo(:thumb) if !f.object.photo.blank? %>
|
|
||||||
<%= f.input :photo %>
|
|
||||||
<%= f.input :website_link %>
|
|
||||||
<%= remove_association_link :lodging, f %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
6
app/views/admin/lodgings/edit.html.haml
Normal file
6
app/views/admin/lodgings/edit.html.haml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%h1
|
||||||
|
Edit Lodging
|
||||||
|
.row
|
||||||
|
.col-md-8
|
||||||
|
= semantic_form_for(@lodging, :url => admin_conference_lodging_path(@conference.short_title, @lodging)) do |f|
|
||||||
|
= render partial: 'form', locals: { f: f }
|
||||||
|
|
@ -1,5 +1,26 @@
|
||||||
.row
|
%h1 Lodgings
|
||||||
.col-md-8
|
- if @venue.lodgings.any?
|
||||||
= semantic_form_for(@venue, :url => admin_conference_lodging_path(@conference.short_title, @conference.venue.lodgings), :html => {:multipart => true}) do |f|
|
.row
|
||||||
= dynamic_association :lodgings, "Lodgings", f
|
.col-md-12
|
||||||
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
%table.table
|
||||||
|
%thead
|
||||||
|
%th #
|
||||||
|
%th Name
|
||||||
|
%th Edit
|
||||||
|
%th Delete
|
||||||
|
%tbody
|
||||||
|
- @venue.lodgings.each_with_index do |lodging, index|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= index + 1
|
||||||
|
%td
|
||||||
|
= link_to lodging.name, admin_conference_lodging_path(@conference.short_title, lodging.id)
|
||||||
|
%td
|
||||||
|
= link_to 'Edit', edit_admin_conference_lodging_path(@conference.short_title, lodging.id),
|
||||||
|
method: :get, class: 'btn btn-primary'
|
||||||
|
%td
|
||||||
|
= link_to 'Delete', admin_conference_lodging_path(@conference.short_title, lodging.id),
|
||||||
|
method: :delete, class: 'btn btn-danger', data: { confirm: "Do you really want to delete the lodging #{lodging.name}?" }
|
||||||
|
|
||||||
|
= link_to 'Add Lodging', new_admin_conference_lodging_path(@conference.short_title), class: 'btn btn-success'
|
||||||
|
|
||||||
|
|
|
||||||
6
app/views/admin/lodgings/new.html.haml
Normal file
6
app/views/admin/lodgings/new.html.haml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%h1
|
||||||
|
New Lodging
|
||||||
|
.row
|
||||||
|
.col-md-8
|
||||||
|
= semantic_form_for(@lodging, :url => admin_conference_lodgings_path(@conference.short_title, @lodging)) do |f|
|
||||||
|
= render partial: 'form', locals: { f: f }
|
||||||
16
app/views/admin/lodgings/show.html.haml
Normal file
16
app/views/admin/lodgings/show.html.haml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
%h1
|
||||||
|
= @lodging.name
|
||||||
|
- unless @lodging.photo.blank? || @lodging.description.blank? || @lodging.website_link.blank?
|
||||||
|
.div.thumbnail
|
||||||
|
- unless @lodging.photo.blank?
|
||||||
|
= image_tag @lodging.photo(:large), class: 'img-responsive'
|
||||||
|
- unless @lodging.description.blank?
|
||||||
|
.lead.text-center #{ markdown(@lodging.description) }
|
||||||
|
- unless @lodging.website_link.blank?
|
||||||
|
.text-center
|
||||||
|
= link_to 'Go to Website', @lodging.website_link
|
||||||
|
|
||||||
|
= link_to 'Edit', edit_admin_conference_lodging_path(@conference.short_title, @lodging.id),
|
||||||
|
method: :get, class: 'btn btn-primary'
|
||||||
|
|
||||||
|
= link_to 'Back', admin_conference_lodgings_path(@conference.short_title)
|
||||||
|
|
@ -52,7 +52,7 @@ Osem::Application.routes.draw do
|
||||||
|
|
||||||
resources :sponsors, only: [:show, :update, :index]
|
resources :sponsors, only: [:show, :update, :index]
|
||||||
|
|
||||||
resources :lodgings, only: [:show, :update, :index]
|
resources :lodgings
|
||||||
|
|
||||||
resources :targets, only: [:update, :index]
|
resources :targets, only: [:update, :index]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,57 +5,84 @@ feature Lodging do
|
||||||
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
||||||
let!(:organizer) { create(:user, role_ids: [organizer_role.id]) }
|
let!(:organizer) { create(:user, role_ids: [organizer_role.id]) }
|
||||||
|
|
||||||
shared_examples 'lodgings' do
|
scenario 'Add a lodging', feature: true, js: true do
|
||||||
scenario 'adds and updates lodgings', feature: true, js: true do
|
path = "#{Rails.root}/app/assets/images/rails.png"
|
||||||
path = "#{Rails.root}/app/assets/images/rails.png"
|
|
||||||
|
|
||||||
conference.venue = create(:venue)
|
conference.venue = create(:venue)
|
||||||
sign_in organizer
|
sign_in organizer
|
||||||
visit admin_conference_lodgings_path(
|
visit admin_conference_lodgings_path(
|
||||||
conference_id: conference.short_title)
|
conference_id: conference.short_title)
|
||||||
# Add lodging
|
# Add lodging
|
||||||
click_link 'Add lodging'
|
click_link 'Add Lodging'
|
||||||
expect(page.all('div.nested-fields').count == 1).to be true
|
|
||||||
page.
|
|
||||||
find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) input').
|
|
||||||
set('Example Hotel')
|
|
||||||
|
|
||||||
page.
|
fill_in 'lodging_name', with: 'New lodging'
|
||||||
find('div.nested-fields:nth-of-type(1) div:nth-of-type(2) textarea').
|
fill_in 'lodging_description', with: 'This is the lodging description'
|
||||||
set('Lorem Ipsum Dolor')
|
fill_in 'lodging_website_link', with: 'http:\\www.google.com'
|
||||||
|
attach_file 'Photo', path
|
||||||
|
|
||||||
attach_file 'Photo', path
|
click_button 'Create Lodging'
|
||||||
|
|
||||||
page.
|
# Validations
|
||||||
find('div.nested-fields:nth-of-type(1) div:nth-of-type(4) input').
|
expect(flash).to eq('Lodging successfully created.')
|
||||||
set('http://www.example.com')
|
expect(page.has_content?('New lodging')).to be true
|
||||||
|
expect(page.has_content?('This is the lodging description')).to be true
|
||||||
click_button 'Update Venue'
|
expect(page.has_content?('Go to Website')).to be true
|
||||||
|
expect(Lodging.count).to eq(1)
|
||||||
# Validations
|
|
||||||
expect(flash).to eq('Lodgings were successfully updated.')
|
|
||||||
|
|
||||||
expect(find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) input').
|
|
||||||
value).to eq('Example Hotel')
|
|
||||||
|
|
||||||
expect(find('div.nested-fields:nth-of-type(1) div:nth-of-type(2) textarea').
|
|
||||||
value).to eq('Lorem Ipsum Dolor')
|
|
||||||
|
|
||||||
expect(page).to have_selector("img[src*='rails.png']")
|
|
||||||
|
|
||||||
expect(find('div.nested-fields:nth-of-type(1) div:nth-of-type(4) input').
|
|
||||||
value).to eq('http://www.example.com')
|
|
||||||
|
|
||||||
# Remove room
|
|
||||||
click_link 'Remove lodging'
|
|
||||||
expect(page.all('div.nested-fields').count == 0).to be true
|
|
||||||
click_button 'Update Venue'
|
|
||||||
expect(flash).to eq('Lodgings were successfully updated.')
|
|
||||||
expect(page.all('div.nested-fields').count == 0).to be true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'organizer' do
|
scenario 'Update a lodging', feature: true, js: true do
|
||||||
it_behaves_like 'lodgings'
|
path = "#{Rails.root}/app/assets/images/rails.png"
|
||||||
|
|
||||||
|
venue = create(:venue)
|
||||||
|
lodging = create(:lodging, venue: conference.venue)
|
||||||
|
conference.venue = venue
|
||||||
|
|
||||||
|
sign_in organizer
|
||||||
|
visit admin_conference_lodgings_path(
|
||||||
|
conference_id: conference.short_title)
|
||||||
|
|
||||||
|
expect(page.has_content?('Example Hotel')).to be true
|
||||||
|
|
||||||
|
# Add lodging
|
||||||
|
click_link 'Example Hotel'
|
||||||
|
click_link 'Edit'
|
||||||
|
|
||||||
|
fill_in 'lodging_name', with: 'New lodging'
|
||||||
|
fill_in 'lodging_description', with: 'This is the lodging description'
|
||||||
|
fill_in 'lodging_website_link', with: 'http:\\www.google.com'
|
||||||
|
attach_file 'Photo', path
|
||||||
|
|
||||||
|
click_button 'Update Lodging'
|
||||||
|
|
||||||
|
# Validations
|
||||||
|
expect(flash).to eq('Lodging successfully updated.')
|
||||||
|
expect(page.has_content?('New lodging')).to be true
|
||||||
|
expect(page.has_content?('This is the lodging description')).to be true
|
||||||
|
expect(page.has_content?('Go to Website')).to be true
|
||||||
|
lodging.reload
|
||||||
|
expect(lodging.name).to eq('New lodging')
|
||||||
|
expect(lodging.description).to eq('This is the lodging description')
|
||||||
|
expect(lodging.website_link).to eq('http:\\www.google.com')
|
||||||
|
expect(Lodging.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Delete a lodging', feature: true, js: true do
|
||||||
|
venue = create(:venue)
|
||||||
|
create(:lodging, venue: conference.venue)
|
||||||
|
conference.venue = venue
|
||||||
|
|
||||||
|
sign_in organizer
|
||||||
|
visit admin_conference_lodgings_path(
|
||||||
|
conference_id: conference.short_title)
|
||||||
|
|
||||||
|
expect(page.has_content?('Example Hotel')).to be true
|
||||||
|
|
||||||
|
# Add lodging
|
||||||
|
click_link 'Delete'
|
||||||
|
|
||||||
|
# Validations
|
||||||
|
expect(flash).to eq('Lodging successfully deleted.')
|
||||||
|
expect(page.has_content?('Example Hotel')).to be false
|
||||||
|
expect(Lodging.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,5 @@ describe 'admin/lodgings/index' do
|
||||||
assign :venue, @conference.venue
|
assign :venue, @conference.venue
|
||||||
render
|
render
|
||||||
expect(rendered).to include('Example Hotel')
|
expect(rendered).to include('Example Hotel')
|
||||||
expect(rendered).to include('Lorem Ipsum Dolor')
|
|
||||||
expect(rendered).to include('http://www.example.com')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue