在Ruby on Rails中创建对象时,您更喜欢哪种保存方法,为什么?

时间:2009-04-07 14:50:31

标签: ruby-on-rails ruby activerecord rescue

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

方法1:

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

方法2:

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 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:3)

我认为异常不应该用于常规条件,所以我会说第二种情况更好。

答案 2 :(得分:2)

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

第二种方法是可行的,如果查询没有成功,那么这是您希望作为该特定操作的日常操作的一部分。

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

答案 3 :(得分:1)

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