2017-01-26 9 views
0

は私がで記事を取得:代わりにタイトル:ID投稿タイトルの検証後に、私は検証エラーが発生したとき、ブラウザは投稿のタイトルの以前の値をRailsサーバーに渡しますか?

routes.rbを:

Rails.application.routes.draw do 
#RSS 
get 'feed' => 'posts#feed' 
get 'archive' => 'posts#archive' 
    devise_for :users, controllers: { omniauth_callbacks: "callbacks" } 
    root to: "posts#index" 

    resources :posts, param: :title do 
    resources :comments, only: [:new, :create, :destroy] 

    resources :images do 
     resources :comments, only: [:new, :create] 
    end 

    resources :links do 
     resources :comments, only: [:new, :create] 
    end 
    resources :photos, only: [:new, :create,:destroy] 
    resources :songs, only: [:new, :create, :destroy] 
    end 

post_controller:私は私の記事のタイトルドットに含まれている場合

class PostsController < ApplicationController 
    before_action :authenticate_user!, only: [:new, :create, :show] 
    respond_to :html, :json, :rss, :atom 
    def index 
    if params[:search].blank? 
     @posts = Post.includes(:comments, :photos).all 
    else 
     @search = Post.search do 
     fulltext params[:search] 
     end 
     @posts = @search.results 
    end 
    respond_with(@posts) 
    end 

    def show 
    set_post 
    end 

    def new 
    @post = Post.new 
    end 

    def edit 
    @post = Post.find_by(title: params[:title]) 
    end 

    def create 
    @post = Post.new(post_params) 
    @post.errors.add(:base, :invalid) unless @post.save 
    respond_with(@post) 
    end 

    def update 
    set_post # this @post dont get post becouse browser pass wrong title and rails dont find it 
    if @post.valid? # here error becouse @post hasnt find 
     @post.update(post_params) 
    else 
     @post.errors.add(:base, :invalid) 
    end 
    respond_with(@post) 
    end 

    def destroy 
    set_post 
    @post.destroy 
    respond_with(@post) 
    end 

    def feed 
    @posts = Post.all.reverse 
    respond_with(@posts) 
    end 

    def archive 
    @posts_by_year = Post.limit(300).all.order("created_at DESC"). 
    group_by {|post| post.created_at.beginning_of_year} 
    end 

    private 

    def set_post 
    #fix N+1 queries and find by posts title 
    @post = Post.includes(:comments, :photos, :links).find_by(title: params[:title]) 
    end 


    def post_params 
    params.require(:post).permit(:title, :content) 
    end 
end 

私は、新しい投稿を作成、私はRailsエラーから出ます。したがって、私はこの形式の検証形式:方法を使用します。

post.rb:私はポストを更新ときは、この後

class Post < ActiveRecord::Base 
    #overwrite the to_param for changing routes from posts/id to posts/title 
    def to_param 
    title 
    end 

    has_many :comments, dependent: :destroy, as: :commentable 
    has_many :images, dependent: :destroy 
    has_many :links, dependent: :destroy 
    has_many :photos, dependent: :destroy 
    has_many :songs, dependent: :destroy 

    validates :content, presence: true 
    validates :title, presence: true, length: { maximum: 100 } 
    validates :title, format: { without: /\./, 
           message: "must be without dot" } 

    searchable do 
    text :title, :content 
    end 
end 

、私の検証formatメソッドは動作し、私は私の検証メッセージは、「ドットなしでなければなりません」を取得します。まあ。私は私の投稿のタイトル入力フィールドのドットを削除し、フォームを送信します。 今ブラウザはサーバに前の投稿のタイトル値をドットで送信します。

Started PATCH "/posts/my%20test%20post%20title%20with%20dot." for 127.0.0.1 at 2017-01-26 11:57:34 +0300 

ActionController::RoutingError (No route matches [PATCH] "/posts/my%20test%20post%20title%20with%20dot."): 

したがってレールは、ドットとタイトルで記事を見つけることができませんAN私はエラーを取得します。 この問題を解決するにはどうすればよいですか?たぶん:代わりにタイトル:この場合のIDは悪い考えですか?

答えて

1

form_forを使用しているとしますか? Railsはpostオブジェクトのタイトルを設定し、検証を実行します。それが失敗すると、編集ビューが表示されます。form_forは、to_paramメソッドを使用してURLを設定し、更新された投稿のタイトルを使用します。もう一度試してみると、URLのタイトルを使って投稿を検索しますが、そのタイトルのデータベースに投稿がないのでできません。

friendly_idのようなものを使用する必要がありますが、実際に自分自身をロールしたいのであれば、単純な実装ではタイトルに基づいて設定されたスラグカラムを持つことになります。しかし明らかに、個人的には個人的に私はフレンドリーなIDやスラグを扱う別の宝石に切り替えるだろう。

関連する問題