登陆URL开始创建新对象最容易rails友好,绕过对表单的需求是什么?
假设我有 3 个模型:
- 商
- 客户
- 额定值
一个企业有很多客户,一个客户有一个评级。
示例:您如何评价您在 XYZ 餐厅的餐点:1、2 或 3?(每个链接都是单独的链接,可以节省 1/2/3 的分数)
我的评级#new和评级#创建方法和路线需要是什么样子才能完成此操作?
我能够通过创建一种全新的方法使其工作,您可以在下面看到:
示例网址:abc.com/ratings/:customer_token/:score
def rate
@customer = Customer.find_by_token(params[:customer_token])
@business = @customer.business
unless @customer.ratings.exists?
@rating = @customer.ratings.new
@rating.customer_id = @customer.id
@rating.business_id = @business.id
@rating.score = params[:score].to_i
@rating.save
if @rating.save
redirect_to :action => 'thanks'
end
end
结束
虽然上述方法有效,但我知道这不是一个好方法。希望得到一些建议!
编辑:我想明确表示,我想生成的链接将来自电子邮件客户端,所以我不能在那里使用Ruby逻辑或任何类型的javascript。
我赞扬你提出了一个表面上有效的解决方案,但我可以看到一个问题......如果实际上是您创建的创建GET
操作的link_to
,那么您最终可能会收到来自网络爬虫的意外帖子!
想象一下谷歌的蜘蛛跟踪你网站上的每个链接......他们将找到指向客户的链接,他们将找到评级链接,通过点击评级链接,他们将创建评级! 这就是为什么创建、更改或删除数据的操作永远不应该落后于GET
操作的原因。
考虑使用button_to
帮助程序来创建本质上执行POST
的按钮(并修改路由以接受对显示 URL 的POST
)
button_to('Rate 1', customer_token: @customer.token, rating: 1)
我猜客户属于企业? @business = @customer.business
.如果一个客户对两个企业进行评分,则有两个客户记录?
另外,您不需要第一个@rating.save
...第二个是重复保存。但这是一个小问题。
您提出的方法有风险的原因是它将所有参数嵌套在 URL get 流中,而无需通过发布流进行验证。有人可能会在您的URL中输入一些可笑的东西并添加一些奇怪的内容,例如abc.com/ratings/[legit customer token]/55
,您的代码会在您的数据库中获得55分(满分3分)的评分。
您仍然可以使用带有隐藏变量的表单来创建评级。您仍然可以将 1、2 和 3 作为链接(如按钮)的内容来提交该表单。
#in your view
<% 3.times do |i| %>
<%= form_for @rating, action: :rate do |f| %>
<%= f.hidden_field :score, value: i %>
<%= f.hidden_field :customer_id, value: @customer.id %>
<%= f.hidden_field :business_token, value: @business.id %>
<%= f.submit i %>
<% end %>
<% end %>
和
#in your controller
def rate
@rating = Rating.new(rating_params)
if @rating.save
#handle success
else
#handle error
end
end
private
def rating_params
params.require(:rating).permit(:rating, :customer_id, :business_id)
end
唯一的选择(除了 AJAX 调用)是使用 link_to 帮助程序,方法POST
:
link_to 'Rate', ratings_path(score: 1, customer_token: 123), method: :post
虽然这看起来不像代码库中的表单,但 Rails 将使用 jquery-ujs 并使用 JavaScript 生成表单。
您的控制器只需使用params
找到合适的Customer
并添加带有分数的rating
。
希望对您有所帮助!