1

私のアプリには、主にこのrailscastに基づいたコメントシステムがあります。現在、私のモデルではto_param、ID が URL に含まれないようにランダムな文字列に変更しています。しかし、それはコメントを壊します。

status.rb

class Status < ActiveRecord::Base
    attr_accessible :content, :member_id, :document_attributes, :permalink
    belongs_to :member 
    belongs_to :document
    has_many :comments, as: :commentable, dependent: :destroy

    before_create :make_it_permalink

    accepts_nested_attributes_for :document

    def to_param
        permalink
    end

    private

    def make_it_permalink
        # this can create permalink with random 12 digit alphanumeric
        self.permalink = SecureRandom.hex(12)
    end

end

statuses_controller.rb

class StatusesController < ApplicationController

before_filter :authenticate_member!, only: [:index, :new, :create, :destroy] 
before_filter :find_member

rescue_from ActiveRecord::RecordNotFound do
    render file: 'public/404', status: 404, formats: [:html]
end

def index
    @statuses = Status.order('created_at desc').page(params[:page]).per_page(21)
    respond_to do |format|
      format.html # index.html.erb
      format.js
    end
end

def show
    @status = Status.find_by_permalink(params[:id])
    @commentable = @status
    @comments = @commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
    @comment = @commentable.comments.new
    respond_to do |format|
      format.html # show.html.erb
      format.json { redirect_to profile_path(current_member) }
    end
end

def new
    @status = Status.new
    @status.build_document

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @status }
      format.js
    end
end

def create
    @status = current_member.statuses.new(params[:status])

    respond_to do |format|
      if @status.save
        @activity = current_member.create_activity(@status, 'created')
        format.html { redirect_to :back }
        format.json
        format.js
      else
        format.html { redirect_to profile_path(current_member), alert: 'Post wasn\'t created. Please try again and ensure image attchments are under 10Mbs.'  }
        format.json { render json: @status.errors, status: :unprocessable_entity }
        format.js
      end
    end
end

def destroy
    @status = current_member.statuses.find(params[:id])
    @activity = Activity.find_by_targetable_id(params[:id])
    @commentable = @status
    @comments = @commentable.comments
    if @activity
      @activity.destroy
    end
    if @comments
      @comments.destroy
    end 
    @status.destroy

    respond_to do |format|
      format.html { redirect_to profile_path(current_member) }
      format.json { head :no_content }
    end
end

private

def find_member
    @member = Member.find_by_user_name(params[:user_name])
end 

def find_status
    @status = current_member.statuses.find_by_permalink(params[:id])
end  

end

コメント_コントローラー.rb

class CommentsController < ApplicationController

before_filter :authenticate_member!
before_filter :load_commentable
before_filter :find_member

def index
    redirect_to root_path
end

def new
    @comment = @commentable.comments.new
end

def create
    @comment = @commentable.comments.new(params[:comment])
    @comments = @commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
    @comment.member = current_member
    respond_to do |format|
      if @comment.save
        format.html { redirect_to :back }
        format.json
        format.js
      else
        format.html { redirect_to :back }
        format.json
        format.js
      end
    end 
end

def destroy
    @comment = Comment.find(params[:id])
    respond_to do |format|
      if @comment.member == current_member || @commentable.member == current_member
        @comment.destroy
        format.html { redirect_to :back }
        format.json
        format.js
      else
        format.html { redirect_to :back, alert: 'You can\'t delete this comment.' }
        format.json
        format.js
      end
    end 
end

private

# def load_commentable
#       resource, id = request.path.split('/')[1,2] # photos/1/
#       @commentable = resource.singularize.classify.constantize.find(id) # Photo.find(1)
# end 

# alternative option:
def load_commentable
    klass = [Status, Medium, Project, Event, Listing].detect { |c| params["#{c.name.underscore}_id"] }
    @commentable = klass.find(params["#{klass.name.underscore}_id"])
end

#def load_commentable
#  @commentable = params[:commentable_type].camelize.constantize.find(params[:commentable_id])
#end

def find_member
    @member = Member.find_by_user_name(params[:user_name])
end 

end

問題は のload_commentableメソッドにありcomments_controllerます。メソッドのいくつかの異なるバリエーションを試しましたが、2番目の方法が私のアプリに最適で、URLにIDが含まれている場合に機能していました。しかし、ランダムなパーマリンクを使用するために を上書きしたため、 と等しい場所to_paramを見つけようとしているため、コメントが機能しなくなりました。URLからIDを見つけようとしているように見えるので、パーマリンクではなく実際のIDを渡すにはどうすればよいですか、またはIDの代わりにパーマリンクで見つけるにはどうすればよいですか?idpermalinkcommentable

4

1 に答える 1

1

パラメータが常に id の値になるか、常にパーマリンクになるか、または場合によっては id になり、場合によってはパーマリンクになるかを判断するのは困難です。

常にパーマリンクにする場合は、次のようにします。

@commentable = klass.find_by_permalink(params["#{klass.name.underscore}_id"])

それ以外の

@commentable = klass.find(params["#{klass.name.underscore}_id"])

場合によっては id であり、場合によってはその他の場合は、クラスに基づいてどちらが必要かを判断するためのロジックを作成する必要があります。

于 2014-07-21T04:30:19.740 に答える