Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 重构相关嵌套if_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 重构相关嵌套if

Ruby on rails 重构相关嵌套if,ruby-on-rails,ruby,Ruby On Rails,Ruby,我试图在create方法中创建两个相关模型,其中第二个模型是使用model1.model2s.build创建的。model*_params只是Rails的4个强参数 因此,我的create方法中有一组代码: def create @model1 = current_user.model1.build(model1_params) if @model1.save @model2 = @model1.model2s.build(model2_params) if @mod

我试图在create方法中创建两个相关模型,其中第二个模型是使用
model1.model2s.build
创建的。
model*_params
只是Rails的4个强参数

因此,我的create方法中有一组代码:

def create
  @model1 = current_user.model1.build(model1_params)

  if @model1.save
    @model2 = @model1.model2s.build(model2_params)

    if @model2.save
      redirect_to model1_path(@model1)
    else
      render 'new'
    end
  else
    render 'new'
  end
end
正如您所看到的,在方法中有一个丑陋的嵌套if,它不是干的,因为我不得不重复
渲染“new”
,以捕获保存失败。这是我保存
model2
的唯一方法,因为它需要与
model1
的关系,并且
model1
必须先保存,才能将
model1
的id传播到构建方法


因此,我的问题是,如何重构这组代码,使其不需要嵌套的if?

您可以轻松地将其设置为单个
if
/
else

if @model1.save && @model1.model2s.build(model2_params).save
  redirect_to @model1
else
  render 'new'
end
或者,例外情况:

begin
  @model1 = current_user.model1.build(model1_params)
  @model1.save!
  @model2 = @model1.model2s.build(model2_params)
  @model2.save!

  redirect_to @model1
rescue ActiveRecord::RecordInvalid => e
  render 'new'
end

我喜欢使用&&运算符,遗憾的是,这对我不起作用。我在调试后发现这是因为我有一个验证来验证关联的存在(
model1\u id
),并且因为
model2
被认为是无效的(因为
model1\u id
model1
保存之前是
nil
)。理想情况下,无论是model1还是model2都不应该创建,因为它们都是无效的。有趣的是,这意味着我的代码是错误的。那么,在这个问题上,你有更大的问题,我们无法真正为你解决。这一点很好。我会接受你的答案,主要是因为我发现它更符合Rails的做事方式,我将针对主要问题提出另一个问题。你不应该使用异常来挽救验证错误。请参阅@SimoneCarletti Yes,Rails中充斥着故意违反公认OOP原则的行为。我考虑过这样的解决方案,(
渲染“new”并返回,除非@model1.save
),但拒绝了它,因为它不符合删除重复的
渲染“new”调用的要求。然而,我认为这是我个人使用的解决方案。。。
def create
  @model1 = current_user.model1.build(model1_params)
  return render("new") unless @model1.save
  @model2 = @model1.model2s.build(model2_params)
  return render("new") unless @model2.save
  redirect_to model1_path(@model1)
end