title: Rails vanity URL preventing #edit from working
body: <p>Users can create and edit stories (basically blogs). I set up a custom vanity URL for the stories, so instead of just the incrementing id, it displays <code>/stories/1-some-story-title</code>. That works well for #show, but when I try to edit the story, (which uses the <code>/stories/1-some-story-title/edit</code> route) I see an error:</p>
  <pre class="lang-rb prettyprint-override"><code>Routing Error:
  No route matches [POST] &quot;/stories/1-some-story-title/edit&quot;
  </code></pre>
  <p>However if I try to visit the non-vanity URL manually (<code>/stories/1/edit</code>) it works, so it's definitely something with the vanity URL not being looked up in the db properly, I just haven't been able to sort out exactly why yet.</p>
  <p>It seems odd to me that Rails can lookup the story without issue for #show, but runs into issues with #edit</p>
  <p>It's worth noting that I'm using <code>Active Admin</code>, and <code>Action Text</code> (Trix) as well.</p>
  <p>Any guidance is appreciated. I'm still getting the hang of Rails, so any articles you've found helpful are certainly welcome too.</p>
  <hr />
  <h2>Stories Controller #show, #edit and #update</h2>
  <pre class="lang-rb prettyprint-override"><code>  def show
      @story = Story.find(params[:id])
    end
  
    def edit
      @story = Story.find(params[:id])
      unless @current_user.is_admin?
        redirect_to root_path if @story.created_at &lt; 2.hours.ago
        redirect_to root_path unless @current_user == @story.user
      end
    end
  
    def update
      @story = Story.find(params[:id])
      if @story.user == @current_user || @current_user.is_admin?
        if @story.update(form_params)
          redirect_to story_path(@story)
        else
          render 'edit'
        end
      else
        redirect_to root_path
      end
    end
  </code></pre>
  <hr />
  <h3>models/story.rb</h3>
  <pre><code>class Story &lt; ApplicationRecord
  
  
    # A story can have many comments
    has_many :comments, dependent: :destroy
    # A story can have many favourites
    has_many :favourites, dependent: :destroy
    # A story can only belong to one user
    belongs_to :user
  
    # Add Trix Rich Text Editor
    has_rich_text :body
  
    # Add image uploader
    mount_uploader :image, ImageUploader
  
    validates :title, presence: true
    validates :body, presence: true, length: { minimum: 10 }
  
    # Changing story URL from number to story title
    def to_param
      id.to_s + '-' + title.parameterize
    end
  
  end
  
  </code></pre>
  <hr />
  <h3>Routes.rb</h3>
  <pre class="lang-rb prettyprint-override"><code>Rails.application.routes.draw do
    ActiveAdmin.routes(self)
    # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  
    # Routes for stories
    resources :stories do
      resources :comments
      resource :favourite
    end
  
    # routes for users
    resources :users
    # Routes for sessions
    resource :session
  
    # Set homepage as stories index page
    root 'stories#index'
  
    # Add new pages and their urls
    get 'about', to: 'pages#about'
    get 'our-story', to: 'pages#our_story'
    get 'terms-and-conditions', to: 'pages#terms'
  
    get 'favourites', to: 'favourites#index'
  end
  
  </code></pre>
  <hr />
  <h3>schema.rb</h3>
  <pre class="lang-rb prettyprint-override"><code>ActiveRecord::Schema.define(version: 2021_05_17_183348) do
  
    create_table &quot;action_text_rich_texts&quot;, force: :cascade do |t|
      t.string &quot;name&quot;, null: false
      t.text &quot;body&quot;
      t.string &quot;record_type&quot;, null: false
      t.bigint &quot;record_id&quot;, null: false
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.index [&quot;record_type&quot;, &quot;record_id&quot;, &quot;name&quot;], name: &quot;index_action_text_rich_texts_uniqueness&quot;, unique: true
    end
  
    create_table &quot;active_admin_comments&quot;, force: :cascade do |t|
      t.string &quot;namespace&quot;
      t.text &quot;body&quot;
      t.string &quot;resource_type&quot;
      t.integer &quot;resource_id&quot;
      t.string &quot;author_type&quot;
      t.integer &quot;author_id&quot;
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.index [&quot;author_type&quot;, &quot;author_id&quot;], name: &quot;index_active_admin_comments_on_author&quot;
      t.index [&quot;namespace&quot;], name: &quot;index_active_admin_comments_on_namespace&quot;
      t.index [&quot;resource_type&quot;, &quot;resource_id&quot;], name: &quot;index_active_admin_comments_on_resource&quot;
    end
  
    create_table &quot;active_storage_attachments&quot;, force: :cascade do |t|
      t.string &quot;name&quot;, null: false
      t.string &quot;record_type&quot;, null: false
      t.integer &quot;record_id&quot;, null: false
      t.integer &quot;blob_id&quot;, null: false
      t.datetime &quot;created_at&quot;, null: false
      t.index [&quot;blob_id&quot;], name: &quot;index_active_storage_attachments_on_blob_id&quot;
      t.index [&quot;record_type&quot;, &quot;record_id&quot;, &quot;name&quot;, &quot;blob_id&quot;], name: &quot;index_active_storage_attachments_uniqueness&quot;, unique: true
    end
  
    create_table &quot;active_storage_blobs&quot;, force: :cascade do |t|
      t.string &quot;key&quot;, null: false
      t.string &quot;filename&quot;, null: false
      t.string &quot;content_type&quot;
      t.text &quot;metadata&quot;
      t.string &quot;service_name&quot;, null: false
      t.bigint &quot;byte_size&quot;, null: false
      t.string &quot;checksum&quot;, null: false
      t.datetime &quot;created_at&quot;, null: false
      t.index [&quot;key&quot;], name: &quot;index_active_storage_blobs_on_key&quot;, unique: true
    end
  
    create_table &quot;active_storage_variant_records&quot;, force: :cascade do |t|
      t.integer &quot;blob_id&quot;, null: false
      t.string &quot;variation_digest&quot;, null: false
      t.index [&quot;blob_id&quot;, &quot;variation_digest&quot;], name: &quot;index_active_storage_variant_records_uniqueness&quot;, unique: true
    end
  
    create_table &quot;comments&quot;, force: :cascade do |t|
      t.text &quot;body&quot;
      t.integer &quot;story_id&quot;, null: false
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.integer &quot;user_id&quot;
      t.index [&quot;story_id&quot;], name: &quot;index_comments_on_story_id&quot;
    end
  
    create_table &quot;favourites&quot;, force: :cascade do |t|
      t.integer &quot;story_id&quot;, null: false
      t.integer &quot;user_id&quot;, null: false
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.index [&quot;story_id&quot;], name: &quot;index_favourites_on_story_id&quot;
      t.index [&quot;user_id&quot;], name: &quot;index_favourites_on_user_id&quot;
    end
  
    create_table &quot;pages&quot;, force: :cascade do |t|
      t.string &quot;title&quot;
      t.text &quot;body&quot;
      t.string &quot;url&quot;
      t.string &quot;image&quot;
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
    end
  
    create_table &quot;stories&quot;, force: :cascade do |t|
      t.string &quot;title&quot;
      t.text &quot;body&quot;
      t.string &quot;topic&quot;
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.integer &quot;user_id&quot;
      t.string &quot;image&quot;
    end
  
    create_table &quot;users&quot;, force: :cascade do |t|
      t.string &quot;first_name&quot;
      t.string &quot;last_name&quot;
      t.string &quot;username&quot;
      t.string &quot;email&quot;
      t.string &quot;password_digest&quot;
      t.datetime &quot;created_at&quot;, precision: 6, null: false
      t.datetime &quot;updated_at&quot;, precision: 6, null: false
      t.boolean &quot;is_admin&quot;, default: false
      t.string &quot;avatar&quot;
    end
  
    add_foreign_key &quot;active_storage_attachments&quot;, &quot;active_storage_blobs&quot;, column: &quot;blob_id&quot;
    add_foreign_key &quot;active_storage_variant_records&quot;, &quot;active_storage_blobs&quot;, column: &quot;blob_id&quot;
    add_foreign_key &quot;comments&quot;, &quot;stories&quot;
    add_foreign_key &quot;favourites&quot;, &quot;stories&quot;
    add_foreign_key &quot;favourites&quot;, &quot;users&quot;
  end
  
  </code></pre>