Friendly urls for tracks

Don't use tracks ids in urls
Add short_name to tracks and use that in urls as the identifier
This commit is contained in:
AEtherC0r3 2017-06-29 23:39:56 +03:00 committed by Antonios Eleftheriadis
parent 882a1d20c9
commit 95fbd10153
9 changed files with 61 additions and 8 deletions

View file

@ -2,7 +2,7 @@ module Admin
class TracksController < Admin::BaseController
load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource :program, through: :conference, singleton: true
load_and_authorize_resource through: :program
load_and_authorize_resource through: :program, find_by: :short_name
def index; end
@ -53,7 +53,7 @@ module Admin
private
def track_params
params.require(:track).permit(:name, :description, :color)
params.require(:track).permit(:name, :description, :color, :short_name)
end
end
end

View file

@ -7,6 +7,12 @@ class Track < ActiveRecord::Base
before_create :generate_guid
validates :name, presence: true
validates :color, format: /\A#[0-9A-F]{6}\z/
validates :short_name,
presence: true,
format: /\A[a-zA-Z0-9_-]*\z/,
uniqueness: {
scope: :program
}
before_validation :capitalize_color

View file

@ -8,8 +8,9 @@
Track
.row
.col-md-12
= semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track))) do |f|
= semantic_form_for(@track, url: (@track.new_record? ? admin_conference_program_tracks_path : admin_conference_program_track_path(@conference.short_title, @track.short_name))) do |f|
= f.input :name
= f.input :short_name, hint: "A short and unique handle for the track, using only letters, numbers, underscores, and dashes. This will be used to identify the track in URLs etc. Example: 'my_awesome_track'", input_html: { required: 'required', pattern: '[a-zA-Z0-9_-]+', title: 'Only letters, numbers, underscores, and dashes.' }
= f.input :color, input_html: {size: 6, type: 'color'}, required: true
= f.input :description, input_html: {rows: 2, data: { provide: 'markdown-editable' } }, hint: markdown_hint
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }

View file

@ -9,6 +9,7 @@
%table.table.table-hover#tracks
%thead
%th Name
%th Short name
%th Description
%th Color
%th Actions
@ -16,8 +17,10 @@
- @tracks.each do |track|
%tr
%td
= link_to(admin_conference_program_track_path(@conference.short_title, track)) do
= link_to(admin_conference_program_track_path(@conference.short_title, track.short_name)) do
= track.name
%td
= track.short_name
%td
%p
= truncate(track.description)
@ -26,9 +29,9 @@
= track.color
%td
.btn-group{role: "group"}
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.id),
= link_to 'Edit', edit_admin_conference_program_track_path(@conference.short_title, track.short_name),
method: :get, class: 'btn btn-primary'
= link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track.id),
= link_to 'Delete', admin_conference_program_track_path(@conference.short_title, track.short_name),
method: :delete, class: 'btn btn-danger',
data: { confirm: "Do you really want to delete #{track.name}? Attention: This track will be removed from all Events that have it set" }
.row

View file

@ -94,7 +94,7 @@
= 'track'
- track = current_or_last_object_state(version.item_type, version.item_id)
= link_if_alive version, track.name,
admin_conference_program_track_path(conference_id: Conference.find(version.conference_id).short_title, id: version.item_id)
admin_conference_program_track_path(conference_id: Conference.find(version.conference_id).short_title, id: track.try(:short_name))
- when 'EventType'
= 'event type'

View file

@ -0,0 +1,39 @@
class AddShortNameToTracks < ActiveRecord::Migration
class TmpProgram < ActiveRecord::Base
self.table_name = 'programs'
end
class TmpTrack < ActiveRecord::Base
self.table_name = 'tracks'
end
def change
add_column :tracks, :short_name, :string
TmpTrack.reset_column_information
TmpProgram.find_each do |program|
# Keeps count of how many times we've encountered a short_name
track_name_counter = {}
TmpTrack.where(program_id: program.id).find_each do |track|
# Replace spaces with undercores and remove the non alphanumeric characters that aren't underscores or dashes
short_name = track.name.tr(' ', '_').tr('^a-zA-Z0-9_-', '')
# If we've seen that short_name before then add the counter in the end to avoid collisions
if track_name_counter[short_name]
track_name_counter[short_name] += 1
short_name += "_#{track_name_counter[short_name]}"
else
# Initialize the counter
track_name_counter[short_name] = 0 unless track_name_counter[short_name]
end
track.short_name = short_name
track.save!
end
end
change_column_null :tracks, :short_name, false
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170603095900) do
ActiveRecord::Schema.define(version: 20170629162450) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -485,6 +485,7 @@ ActiveRecord::Schema.define(version: 20170603095900) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "program_id"
t.string "short_name", null: false
end
create_table "users", force: :cascade do |t|

View file

@ -3,6 +3,7 @@ FactoryGirl.define do
name { Faker::Commerce.department(2, true) }
description { Faker::Lorem.sentence }
color { Faker::Color.hex_color }
short_name { SecureRandom.urlsafe_base64(5) }
program
end
end

View file

@ -14,6 +14,7 @@ feature Track do
click_link 'New Track'
fill_in 'track_name', with: 'Distribution'
fill_in 'track_short_name', with: 'Distribution'
page.find('#track_color').set('#B94D4D')
fill_in 'track_description', with: 'Events about our Linux distribution'
click_button 'Create Track'
@ -50,6 +51,7 @@ feature Track do
click_link 'Edit'
fill_in 'track_name', with: 'Distribution'
fill_in 'track_short_name', with: 'Distribution'
page.find('#track_color').set('#B94D4D')
fill_in 'track_description', with: 'Events about our Linux distribution'
click_button 'Update Track'