class ClientSkippedDaysController < ApplicationController
before_action :check_client_on_exist, only: [:create]
def index
@client_skipped_days = ClientSkippedDay.order_by(params[:sort_by], params[:direction])
if params[:date].present?
@client_skipped_days = @client_skipped_days.where('skipped_at = ?', Date.parse(params[:date]))
end
render json: @client_skipped_days, status: :ok
end
def create
@client_skipped_days = ClientSkippedDay.create!(client_skipped_days_params)
render json: @client_skipped_days, status: :created
end
def destroy
end
private
def client_skipped_days_params
params.permit(client_skipped_days: %i[client_id skipped_at])[:client_skipped_days]
end
def check_client_on_exist
client_skipped_days_params.each do |day|
ClientSkippedDay.find_by(day)&.destroy
end
end
end
如果我尝试仅删除一条记录(例如:
),我的代码将起作用Parameters: {"client_skipped_days"=>[{"client_id"=>533, "skipped_at"=>"2019-02-24"}], "client_skipped_day"=>{}}
但是,如果我尝试删除数组中的每个哈希,那是行不通的:(
Parameters: {"client_skipped_days"=>[{"client_id"=>533, "skipped_at"=>"2019-02-24"}, {"client_id"=>512, "skipped_at"=>"2019-02-24"}], "client_skipped_day"=>{}}
将仅删除一条记录,但是如何添加删除所有记录的功能?与控制器的参数一致?
它必须是一个灵活的系统,可以删除数组中是否包含1个哈希,并立即删除数组中的哈希集合。告诉我怎么做。
答案 0 :(得分:1)
您需要遍历数组,而不仅仅是从数组中取出第一个值。我不了解您拥有的参数,因此假设您要使用find_by
和client_id
的哈希值来完成skipped_at
。
此外,Ruby 2.3.0引入了安全导航运算符,如果您不习惯&.
的话,这就是它。 http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
由于find_by
返回ActiveRecord对象或返回nil,因此现在是使用安全导航运算符缩短时间的绝佳时机。
def client_skipped_days_params
params.permit(client_skipped_days: %i[client_id skipped_at])[:client_skipped_days]
end
def check_client_on_exist
client_skipped_days_params.each do |day|
ClientSkippedDay.find_by(day)&.destroy
end
end
注意,我不确定您的client_skipped_day哈希是多少。我认为您可以删除一天或批量删除。我警告不要让它做两件事。只需使客户端始终为此操作发送一个数组,事情对您来说将变得更容易。如果可以这样做,则可以使client_skipped_days
为必需。
def client_skipped_days_params
params.require(:client_skipped_days).permit(%i[client_id skipped_at])
end
如果客户端不提供client_skipped_days密钥,则会向客户端引发422错误。
如果这不可能,那么您需要向if
添加check_on_exist
以确保client_skipped_days_params
不为空(因为他们使用的是{{1 }}。
答案 1 :(得分:1)
您可以考虑使用多个#where
查询,而不是遍历params
并逐个查找每条记录,而将它们与#or
结合使用,并遍历结果记录
def client_skipped_days_params
params.permit(client_skipped_days: [:client_id, :skipped_at])
# removed `.values` ^
end
def check_client_on_exist
destroyed_records, undestroyed_records =
client_skipped_days_params
.fetch(:client_skipped_days, []) # get the array or use an empty array as default
.map(&ClientSkippedDay.method(:where)) # build individual queries
.reduce(ClientSkippedDay.none, :or) # stitch the queries together using #or
.partition(&:destroy) # call #destroy on each item in the collection, separating destroyed once from undestroyed once
end
在上面的示例中,生成的销毁记录存在于destroyed_records
变量中,而无法销毁的记录存在于undestroyed_records
变量中。如果您不关心结果,则可以将其省略。如果您想在无法销毁记录的情况下引发异常,请改用#destroy!
(调用每个收集项)。
或者,您可以通过调用#destroy_all
(在集合上调用)销毁所有记录,但是它只会返回一个记录数组,而不会将销毁的记录与未销毁的记录区分开。该方法仍将实例化记录并逐个销毁它们,其优点是仍会触发回调。
更快的选项是调用#delete_all
(在集合上调用)。这将用一个查询破坏所有记录。 但是销毁记录时不会实例化,这意味着将不会触发回调。
def check_client_on_exist
destroyed_record_count =
# ...
.reduce(ClientSkippedDay.none, :or)
.delete_all # delete all records with a single query (without instantiation)
end
引用: