使用强参数作为服务器端自动完成资源

时间:2016-05-26 01:45:43

标签: ruby-on-rails jquery-ui

使用this railscast,除了我正在使用Rails 5,其中不推荐使用attr_accessible。 VenueSuggestion是一种资源,用于在数据库中建议场所,因为用户在表单的相关字段中键入内容。我现在遇到的问题是,当我开始输入匹配数据库内容的内容时,没有搜索结果。

模特:

class VenueSuggestion < ApplicationRecord

  # should anything go in place of attr_accessible?

  def self.terms_for(prefix)
    suggestions = where("term like ?", "#{prefix}_%")
    suggestions.order("popularity desc").limit(10).pluck(:term)
  end

  def self.index_venues
    Venue.find_each do |venue|
      index_term(venue.name)
      index_term(venue.address)
      venue.name.split.each { |t| index_term(t) }
    end
  end

  def self.index_term(term)
    where(term: term.downcase).first_or_initialize.tap do |suggestion|
      suggestion.increment! :popularity
    end
  end
end

控制器:

class VenueSuggestionsController < ApplicationController
  #is this right?
  def create
    VenueSuggestion.create(params[:venue_suggestion])
  end

  def index
    render json: VenueSuggestion.terms_for(params[:term])
  end

  # is this right?
  private
        def venue_suggestion_params
            params.require(:venue_suggestion).permit(:term, :popularity)
        end
end

rake任务:

namespace :venue_suggestions do
  desc "Generate venue suggestions for event form"
  task :index => :environment do
    VenueSuggestion.index_venues
  end
end

日志显示的内容:

Started GET "/venue_suggestions?term=sp" for ::1 at 2016-05-25 21:27:31 -0400
Processing by VenueSuggestionsController#index as JSON
  Parameters: {"term"=>"sp"}
   (1.4ms)  SELECT  "venue_suggestions"."term" FROM "venue_suggestions" WHERE (term like 'sp_%') ORDER BY popularity desc LIMIT $1  [["LIMIT", 10]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (0.06ms)
Completed 200 OK in 4ms (Views: 0.6ms | ActiveRecord: 1.4ms)

1 个答案:

答案 0 :(得分:0)

强params功能提供了一个界面,用于保护属性不受最终用户分配的影响。这使得动作控制器参数被禁止在活动模型批量分配中使用,直到它们被列入白名单。

class PeopleController < ActionController::Base
  # Using "Person.create(params[:person])" would raise an
  # ActiveModel::ForbiddenAttributes exception because it'd
  # be using mass assignment without an explicit permit step.
  # This is the recommended form:
  def create
    Person.create(person_params)
  end

  # This will pass with flying colors as long as there's a person key in the
  # parameters, otherwise it'll raise an ActionController::MissingParameter
  # exception, which will get caught by ActionController::Base and turned
  # into a 400 Bad Request reply.
  def update
    redirect_to current_account.people.find(params[:id]).tap { |person|
      person.update!(person_params)
    }
  end

  private
    # Using a private method to encapsulate the permissible parameters is
    # just a good pattern since you'll be able to reuse the same permit
    # list between create and update. Also, you can specialize this method
    # with per-user checking of permissible attributes.
    def person_params
      params.require(:person).permit(:name, :age)
    end
end

请记住,您需要使用类似

的内容在venue_suggestions中指定术语
params = ActionController::Parameters.new(venue_suggestion: { term: "something" })

来源:http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html