【问题标题】:What would be a better way to code this if then else clause?有什么更好的方法来编写 if then else 子句?
【发布时间】:2010-09-16 13:19:47
【问题描述】:

我有以下代码。我仍然是 Ruby on Rails 的新手。正如你所看到的,我重复了自己 4 次。

我尝试过这样的事情:

if @property.nil? || @property.status_id == 144 || (@property.status_id <= 16 && current_user.nil?) || (@property.status_id <= 16 && current_user.id != @property.user_id)

但如果@property 为nil,它会给我很多错误。因为那时@property.status_id 不能被调用,因为@property 为nil。

无论如何,我认为有经验的 Ruby on Rails 编码员会明白这一点。

  def show
    @property = Property.find(params[:id]) rescue nil
    if @property.nil?
      flash[:error]=t("The_property_was_not_found")
      redirect_to root_path
      return
    end
    if @property.status_id == 144
      flash[:error]=t("The_property_was_not_found")
      redirect_to root_path
      return
    end
    if @property.status_id <= 16 && current_user.nil?
      flash[:error]=t("The_property_was_not_found")
      redirect_to root_path
      return
    end
    if @property.status_id <= 16 && current_user.id != @property.user_id
      flash[:error]=t("The_property_was_not_found")
      redirect_to root_path
      return
    end
    @images = Image.find(:all, :conditions =>{:property_id => params[:id]})
  end

【问题讨论】:

  • 通常您不需要让显示页面处理 nil 值。如果一开始就不存在,那么有人怎么能进入显示页面?
  • 您应该将您的测试与&amp;&amp;|| 结合起来,这就是它们的用途。
  • @beerlington 这是一个房地产经纪人网站。从表中删除旧属性,使具有旧链接的访问者收到错误。你说得有道理,也许他们不应该删除旧属性。无论如何,这是一种保障。
  • 这是有道理的。那么current_user.nil? 的逻辑是什么?用户是否也连同属性一起被删除?

标签: ruby-on-rails if-statement logic


【解决方案1】:
def show
    @property = Property.find(params[:id]) rescue nil
    if @property.nil? || @property.status_id == 144 || (@property.status_id <= 16 && (current_user.nil? || current_user.id != @property.user_id))
      flash[:error]=t("The_property_was_not_found")
      redirect_to root_path
    else
      @images = Image.find(:all, :conditions =>{:property_id => params[:id]})
    end
  end

我不熟悉 Ruby 语法,所以这可能无法真正编译,但你明白了。

【讨论】:

  • 嗨,弗拉德,我尝试了类似的方法,请参阅我的一行代码。问题是@property.status_id 在@property 为nil 的情况下会给出错误。然后我调用一个 nil 值的方法。
【解决方案2】:

这真的是确切的代码吗? || short-circuits 和 nil 值应该不是问题。

@property=nil
if @property.nil? || @property.status_id == 144
   puts @property.class.to_s
end

输出 NilClass

【讨论】:

  • 我刚试了你的建议,确实,好像确实短路了。所以我添加了所有 || 和 && 的完整行,它可以工作。不知道为什么我昨天收到了错误。也许是在我添加救援 nil 之前。
【解决方案3】:

我认为你应该通过将“可以显示”逻辑定义为一个简单的帮助方法来解决这个问题,你可以调用它来做出决定,而不是用各种最终使相同操作发生的分支将你的显示方法弄乱。

def can_show_property?(property)
  return false unless (property)

  return false if (property.status_id == 144 or property.status_id > 16)

  return false unless (current_user && current_user.id == property.user_id)

  true
end

def show
  @property = Property.find(params[:id]) rescue nil

  unless (can_show_property?(@property))
    flash[:error]=t("The_property_was_not_found")
    redirect_to root_path
    return
  end

  @images = Image.find(:all, :conditions =>{ :property_id => params[:id] })
end

在您的代码中使用像 144 这样的“神奇”数字确实会导致人们询问为什么没有为它们分配常量。明确标记MyApp::PROPERTY_LOCKED 时通常更容易理解。

【讨论】:

  • 谢谢,这确实是一个更好的方法,原来我也可以将所有条件组合在 1 行中。我还不知道使用常量的技术。我查了一下,确实好多了。感谢您指出这一点。
【解决方案4】:

你可以试试这个:

def show
begin 
  @property = Property.find(params[:id])
  if [144,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0].include?(@property.status_id)
    flash[:error]=t("The_property_was_not_found")
    if current_user && (current_user.id != @property.user_id)
      redirect_to myimmonatie_path 
    else
      redirect_to root_path 
    end
rescue
  flash[:error]=t("The_property_was_not_found")
  redirect_to root_path
end
@images = Image.find(:all, :conditions =>{:property_id => params[:id]})

结束

【讨论】:

  • 哦,很常见,我知道include? 非常Ruby,但是if @property.status_id == 144 || @property.status_id &lt;= 16 有什么问题?
  • ((0..16).to_a
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 2016-05-05
  • 2011-12-15
相关资源
最近更新 更多