3

在 Rails 中,我们定义了create2 种方式的动作。有什么区别?

def create
  @shop = Shop.new(params[:shop])
  if @shop.save
    flash[:success] = 'Thanks for adding new shop.'
    redirect_to @shop
  else
    flash[:error] = 'Error adding review,  please try again.'
    redirect_to @shop
  end
end

# or

def create
  @shop = Shop.create(params[:shop])
  if @shop.save
    flash[:success] = 'Thanks for adding new shop.'
    redirect_to @shop
  else
    flash[:error] = 'Error adding review,  please try again.'
    redirect_to @shop
  end
end

考虑到我们已经有:

def new
  @shop = Shop.new
end

哪个更合适?

4

4 回答 4

3

def new操作仅用于New视图(控制器new中的操作Shop将对应于app/views/shop/new.html.erb文件) - 它不进行任何创建:

def new
  @shop = Shop.new
end

在该操作中没有提及params[:shop],因为参数还不存在 - 这就是您在New视图中收集的内容。

def create的操作是实际创建数据库条目的操作:

def create
  @shop = Shop.new(params[:shop])
  if @shop.save
    flash[:success] = 'Thanks for adding new shop.'
    redirect_to @shop
  else
    flash[:error] = 'Error adding review,  please try again.'
    redirect_to @shop
  end
end

您正在使用.new而不是,.create以便您可以进行验证。此外,Shop.new调用实际上并没有创建记录——它就是@shop.save这样做的。

于 2013-01-28T15:28:55.127 回答
2

第一种方法不符合您的期望:

def create
  @shop = Shop.new(params[:shop]) # This won't create a new record on Shops table unless...
  @show.save                      # ...you do this
end

def create
  @shop = Shop.create(params[:shop]) # This will create a new record if everything is fine
  if @shop.save # This is redundant
    # ...
  end
end

调用createthensave是多余的。如果验证不成功,该create方法将尝试创建新记录并静默失败。另一方面,save将尝试创建新记录,但nil如果验证失败则返回,因此您可以在if/else块中使用它。

于 2013-01-28T15:22:16.560 回答
2

如果使用Model.create,则不需要显式保存对象。create 方法将为您执行此操作。如果你使用Model.new了,你需要通过@object.save 来保存对象。新方法不会为您做到这一点。

使用 Model.new:

def create
  @shop = Shop.new(params[:shop])
   if @shop.save
    flash[:success] = 'Thanks for adding new shop.'
    redirect_to @shop
  else
    flash[:error] = 'Error adding review,  please try again.'
    redirect_to @shop
  end
end

使用 Model.create:

def create
  @shop = Shop.create(params[:shop])
   # if @shop.save (This is not required)
  if @shop 
    flash[:success] = 'Thanks for adding new shop.'
    redirect_to @shop
  else
    flash[:error] = 'Error adding review,  please try again.'
    redirect_to @shop
  end
end
于 2013-01-28T15:31:34.437 回答
1

create控制器动作中,Shop.new没有跟随是没有用的@shop.save。通常它被分成这两个步骤来处理验证错误。我们使用来自用户的数据初始化商店。如果数据正常,我们保存商店。如果存在验证错误,我们会告诉用户重试。

或者我们需要在将记录保存到数据库之前进行一些复杂的属性初始化。

@user = User.new params[:user]
@user.reputation = fetch_reputation_from_stackoverflow

if @user.save
  # the usual steps here

回复:问题编辑

考虑到我们已经有:

def new
  @shop = Shop.new
end

行动中new的内容完全无关紧要。如果您的验证可能失败(或者您的模型可能无法成功创建),请使用new+save对。如果您确定输入数据正常并且模型将始终保存,则仅使用create(以下save是多余的)。

于 2013-01-28T15:21:40.533 回答