7

在 Ruby on Rails 应用程序中为对象编写“创建”方法时,我使用了两种方法。为了更清晰和更一致的代码,我想使用一种方法。我将在下面列出这两种方法。有谁知道一个比另一个更好吗?如果是这样,为什么?

方法一:

def create1
  # is this unsecure? should we grab user_id from the session
  params[:venue]['user_id'] = params[:user_id]

  begin
    venue = Venue.create(params[:venue])
    @user_venues = @user.venues
    render :partial => 'venue_select_box', :success => true, :status => :ok
  rescue ActiveRecord::RecordInvalid
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity
  end
end

方法二:

def create2
   # is this unsecure? should we grab user_id from the session
  params[:venue]['user_id'] = params[:user_id]

  venue = Venue.new(params[:venue])
  if venue.save
    @user_venues = @user.venues
    render :partial => 'venue_select_box', :success => true, :status => :ok
  else
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity
  end
end
4

4 回答 4

4
class VenuesController < ApplicationController
  def create
    @venue = @user.venues.create!(params[:venue])
    render :partial => 'venue_select_box', :success => true, :status => :ok
  end

  rescue_from ActiveRecord::RecordInvalid do
    render :text => 'Put errors in here', :success => false, :status => :unprocessable_entity
  end
end

@user.venues这种方式使用可确保始终正确设置用户 ID。此外,ActiveRecord 将在调用:user_id过程中保护字段不被分配。#create!因此,来自外部的攻击将无法修改:user_id

在您的测试中,您可以验证对 :create 执行 POST 会引发 ActiveRecord::RecordInvalid 异常。

于 2009-04-07T18:23:15.927 回答
3

我认为例外不应该用于常规条件,所以我会说第二个更好。

于 2009-04-07T15:10:55.313 回答
2

这取决于。如果您希望所有 create 语句都能正常工作,请使用前者,因为创建和保存失败是例外情况,并且可能是程序无法轻松恢复的情况。此外,如果您使用关系完整性(RedHill Consulting 的foreign_key_migrations),这将引发外键违规异常,因此您可能希望在创建或更新时捕获它们。

第二个是可行的,如果查询不成功是您期望作为该特定操作的日常操作的一部分的事情,那么这很好。

此外,您关于会话不安全的代码注释 - 会话是放置 user_id 的地方。只要您在执行其他任何操作之前检查以验证用户是否已通过身份验证,就可以了。

于 2009-04-07T15:18:33.580 回答
1

我完全同意唐的评论。但我什至会更进一步使用 user_id 部分并将其设置为模型上的前置过滤器。

于 2009-04-07T15:23:35.253 回答