繁体   English   中英

Ruby on Rails忽略了If Else语句

[英]Ruby on Rails ignoring If Else statement

我的Ruby on Rails 3控制器有一个简单的If Else语句似乎不起作用。

我的发言:

def create
if @trained = Certificate.where(user_id: params[:certificate][:user_id])
  @trained.first.update_attributes(attend: "Yes")
else
  @trained = Certificate.new(params[:certificate])
  if @trained.save
        @trained.update_attributes(attend: "Yes")
  end
end

redirect_to grandstreamers_resellers_path

end

这是带有错误的日志,'update_attributes'的NoMethodError,但是这行不应该运行,因为它找不到带有user_id'1'的证书。 为什么不做else语句呢?

Started POST "/certificates" for 50.241.102.234 at 2014-01-06 07:01:55 -0800
Processing by CertificatesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"TM6GPqslIs013O+mOuxGXyyD90T2O5lSZmnqKTFPwVw=", "certificate"=>{"user_id"=>"1"}, "commit"=>"Train"}
Certificate Load (0.1ms)  SELECT `certificates`.* FROM `certificates` WHERE `certificates`.`user_id` = 1 LIMIT 1
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `update_attributes' for nil:NilClass):
app/controllers/certificates_controller.rb:5:in `create'

where子句永远不会返回nil ,它返回一个ActiveRecord :: Relation对象, 它可以是空的

试试这个:

def create
  if @trained = Certificate.where(user_id: params[:certificate][:user_id]).first
    @trained.update_attributes(attend: "No")
  else
    @trained = Certificate.new(params[:certificate])
    if @trained.save
      @trained.update_attributes(attend: "Yes")
    end
  end

  redirect_to grandstreamers_resellers_path
end

但我会重构我的代码到这样的事情:

def create
  @trained = Certificate.where(user_id: params[:certificate][:user_id]).first
  @trained ||= Certificate.new(params[:certificate])
  if @trained.persisted? # tests if the records is persisted in the DB (has an ID)
    @trained.attend = "No"
  else
    @trained.attend = "Yes"
  end

  @trained.save
  redirect_to grandstreamers_resellers_path
end

非常短的版本:

def create
  @trained = Certificate.where(user_id: params[:certificate][:user_id]).first || Certificate.new(params[:certificate])
  @trained.attend = @trained.persisted? ? "No" : "Yes"
  @trained.save

  redirect_to grandstreamers_resellers_path
end

有关记录(@NitinJ请看一下),您可以在if条件中分配变量:

if first_user = User.first
# if User.first does not returns nil, executes the first block with local variable first_user available
  first_user.id 
else
  # User.first returned nil
end
Certificate.where(user_id: params[:certificate][:user_id])

上面的语句返回一个从不为nil的Relation,因此即使关系为空,条件也将始终为true

如果您期望0或1结果,则可以使用

if @trained = Certificate.where(user_id: params[:certificate][:user_id]).first
   #...

如果你期望0或几个结果,你可以使用(不是很优雅):

if (@trained = Certificate.where(user_id: params[:certificate][:user_id]).to_a) && @trained.any?
   #...

如果条件,你被赋予价值

@trained = Certificate.where(user_id: params[:certificate][:user_id])

改为

@trained = Certificate.where(user_id: params[:certificate][:user_id])
if @trained.exists?
else
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM