如何创建一个没有表单的新对象,仅以 Rails 友好的方式使用 URL 参数



登陆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

希望对您有所帮助!

最新更新