问题:我有一个控制器,我想将更新动作分为3个单独的更新动作...更新所有参数(减去其他更新动作),更新以更改订单状态(创建,取消,收费)和收费更新(仅在将文件上传到订单后收费)
问题:您能帮我指导和指导我完成该方向吗?
我应该如何以最有效和“正确”的方式进行此操作?
我是否应该再创建2个控制器(因为我需要3个更新),一个用于更改订单状态,一个用于收费,并让它们继承OrderController?
还是可以在一个控制器中执行3个更新操作?我试过了,但没弄清楚
这是我“解决”它的方法,但是有时似乎运行不顺畅,有时我注意到将文件上传到订单时,它开始循环播放和/或比将所有文件都放在一个目录下需要更长的时间定义的参数方法:
def update
respond_to do |format|
if @order.update(order_status)
if user_signed_in?
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully order_status.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
if @order.update(order_charge)
@amount = (@order.order_price).to_i * 100
@amount_seller = (@order.order_price).to_i * 75
if @order.update(order_charge)
if current_user.seller?
charge = Stripe::Charge.create({
:amount => @amount,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => @order.stripe_customer_token,
:destination => {
:amount => @amount_seller ,
:account => (@order.seller.stripe_token),
}
})
@order.order_status = "charged"
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
if @order.update(order_params)
if user_signed_in?
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
end
private
def set_order
@order = Order.find(params[:id])
end
def order_params
params.require(:order).permit(:name, :email, :image, :video, :description)
end
def order_status
params.require(:order).permit(:order_status)
end
def order_charge
params.require(:order).permit(:video)
end
...
end
从技术上讲这是可行的,但速度或速度并不理想。当我上传视频时,它会给我order_status消息,这是因为当视频上传时,我会更改订单状态。但是从某种意义上说,它仍然有效。
有没有人开发过一个应用程序,需要在一个控制器和一个模型下执行多个更新操作,并且找到了执行该更新的最佳方法?
尽管上面的代码“有效”,但我被告知效率不高,我应该再创建2个控制器来执行我想做的事情。我想我会先来这里,然后再进行此操作,以让其他人根据他们的经验获得意见,如果他们有与此问题相似的应用程序。
或者除了上述1和2之外,您还有其他想法吗?
(上面的更新操作尚未完成,例如order_status。但是我最担心的是应该如何实际执行此操作。)
答案 0 :(得分:1)
解决此问题的一种方法是只使用一种app.post('/ownerPanel', (req, res) => {
try {
let addBook = books.books.addBookOwner(req.body.book_title, req.body.author,
req.body.price, req.body.subject, req.body.isbn, req.body.Vendor,
req.body.Owner, connection, res);
console.log("addBook", addBook);
if (addBook) {
console.log("in the if in app vendor");
books.books.renderOwner(connection, res);
} else {
let deleteBook = books.books.deleteBook(req.body.isbn, connection, res);
console.log("deleteBook", deleteBook);
if (deleteBook) {
console.log("in the if in app post ");
books.books.renderOwner(connection, res);
} else {
console.log("didn't match either if or else if conditions");
}
}
books.books.renderOwner(connection, res);
} catch(e) {
console.log("ownerPanel exception", e);
res.sendStatus(500);
}
})
方法并删除order_params
和order_charge
,因为无论哪种情况,仅更新一个资源。正如您所说,仅在一种情况下,用户在上传文件时才需要向用户收费,因此请在 controller 中使用助手方法来负责向用户收费。
order_status
在您的更新方法内部,只需更新订单并根据需要向用户收费。就像这样
def charge_amount
@amount = (@order.order_price).to_i * 100
@amount_seller = (@order.order_price).to_i * 75
if current_user.seller?
charge = Stripe::Charge.create({
:amount => @amount,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => @order.stripe_customer_token,
:destination => {
:amount => @amount_seller ,
:account => (@order.seller.stripe_token),
}
})
@order.order_status = "charged"
end
end
采用这种方法,代码将缩小大小并分离逻辑,并且更易于调试。我希望这能回答您的问题,或者至少为您提供一些指导。
更新
如果需要单独的操作,只需在控制器中创建三个方法,然后根据参数的类型在def update
respond_to do |format|
if user_signed_in? #this could be moved to a `before_action` that authenticates the user
if @order.update(order_status)
if order_params[:video].present?
charge = charge_amount
end
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully order_status.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
end
操作中调用适当的方法。
答案 1 :(得分:0)
我最终还是这样做了...多亏了我早些时候找到的一篇SO帖子...
订单控制器:(与更新操作分开:)
def charge_update
respond_to do |format|
@amount = (@order.order_price).to_i * 100
@amount_seller = (@order.order_price).to_i * 75
if @order.update(order_charge)
charge = Stripe::Charge.create({
:amount => (@order.order_price).to_i * 100,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => @order.stripe_customer_token,
:destination => {
:amount => @amount_seller ,
:account => (@order.seller.stripe_token),
}
})
@order.update_column(:order_status, 2)
format.html { redirect_to ([@user, @order]), notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: @order }
else
format.html { render :edit }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
路线:
resources :orders do
member do
patch :charge_update
put :charge_update
end
end
对于视图中的上传:
<%= form_for([@listing, @order], :url => charge_update_order_path ) do |form| %>
...
<%= form.file_field :video %>
...
<%= form.submit "Upload", class: "btn btn-success" %>
控制器的其余部分:(专用部分)
private
def order_charge
params.require(:order).permit(:video, :order_status)
end
现在,上传视频操作是独立的,并且运行速度更快。我在更新订单状态以取消订单方面并没有做同样的事情,在进行更多测试后,我可能会也可能不会。与其他参数区分开来,充电方面是最重要的事情。