rails 检查现有实例属性

Posted

技术标签:

【中文标题】rails 检查现有实例属性【英文标题】:rails check for existing instance attribute 【发布时间】:2010-09-17 11:42:12 【问题描述】:

我正在开发一个社交网站(老实说,基本上是一个 facebook 的副本......)并且我重用了 insoshi 的大部分内容。但是 insoshi 的供稿对我的喜好不够准确。因为它不支持更专业的消息。你会在下面看到我的意思 代码:

item = activity.item
relationship = relationship(item)
case relationship
   when 1
     raw %(<p>You wrote on your own wall: <br/>
     #truncate(item.body, :length => 20)</p>)
   when 2
     raw %(<p>#link_to item.user.name, item.user wrote on your wall</p>)
   when 3
     raw %(<p>#link_to item.user.name, item.user wrote on his wall</p>)
   when 4
     raw %(<p>You wrote on #link_to item.user.name, item.user's wall</p>)
   when 5
     raw %(<p>#link_to item.user.name, item.user wrote on 
              #link_to item.contact.name, item.contact's wall</p>)
end

    def relationship(item) 
        unless item.owner.nil?
          contact = item.owner #so that it works for posts as well
        else
          contact = item.contact
        end
        user = item.user

        if current_user != contact or current_user != user
          return 5
        else
          if current_user == contact
            if current_user == user
              return 1
            else
              return 2
            end
          else
            if contact == user
              return 3
            else
              return 4
            end
          end
        end
end

我有不同类型的物品。通常项目有一个“用户”和一个“联系人”。除了帖子,它们还有一个“用户”和一个“所有者”。因为一个帖子的其他人可以写在别人的墙上(因此是所有者)。

现在,当我尝试将联系人设置为 item.contact 时,问题就出现了......它只是不断地用“NoMethod”错误来困扰我,说 item.contact 不存在。 (如果该项目是帖子而不是“连接”或类似项目,则这一点很明显)。

所以我想征求你的意见: 1)用更多的红宝石解决问题,或者 2) 更改帖子模型,使帖子具有“用户”和“联系人”?

谢谢大家 斯特凡诺

【问题讨论】:

呃。请使用符号而不是整数。 我讨厌做个混蛋,但是这段代码真的很难理解,而且看起来很hacky。我绝对不会通过添加更多代码来解决这个问题。我建议阅读单表继承、多态性,并考虑将 relationship 移动到模型中。 制作一个包含表格的新模型,纯粹是为了自定义助手的输出? @Tass:符号不会让它更混乱吗? :user_same_as_contact, :current_user_same_as_user 我不确定我是否明白你的意思。 @Stefano,我不知道这是一个帮手。我肯定会将这个逻辑转移到模型中。这将使测试和记录变得更容易。 @Beerlington 我同意你的看法,但是如何做到这一点?因为这种关系取决于谁查看了帖子,谁写了帖子,以及帖子是谁... 【参考方案1】:

根据您的逻辑,关系 3 和 4 永远不会返回。我认为你有current_user != contact or current_user != user,你应该有and。就个人而言,我总是使用 && 因为如果第一个条件为假,它会短路。但是,在我的重构中,您不需要它,因为如果没有其他情况匹配,它会返回 5。

我将关系逻辑移至 Item 模型并在帮助程序中进行了适当的更新。

查看助手:

case item.relationship_to_user(current_user)
when 1
  raw %(<p>You wrote on your own wall: <br/>
  #truncate(item.body, :length => 20)</p>)
when 2
  raw %(<p>#link_to item.user.name, item.user wrote on your wall</p>)
when 3
  raw %(<p>#link_to item.user.name, item.user wrote on his wall</p>)
when 4
  raw %(<p>You wrote on #link_to item.user.name, item.user's wall</p>)
when 5
  raw %(<p>#link_to item.user.name, item.user wrote on 
  #link_to item.contact.name, item.contact's wall</p>)
end

物品类别

class Item < ActiveRecord::Base

  def relationship_to_user(current_user)
    contact = owner || contact  

    return 1 if current_user == contact && current_user == user
    return 2 if current_user == contact
    return 3 if current_user != contact
    return 4 if current_user != contact && contact != user

    return 5
    # return 5 if current_user != contact or current_user != user
  end

end

【讨论】:

谢谢,非常感谢。但似乎整数键是要走的路(?) 您可以通过使用常量或符号轻松改进它。 Relationship::FRIENDS:friends【参考方案2】:

我会用 Ruby 代码修复。

contact = item.contact if item.respond_to? :contact

通过使用 respond_to?这适用于任何有联系人的班级。

【讨论】:

以上是关于rails 检查现有实例属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 迁移中添加检查约束?

如何检查特定属性是不是是有效的 ruby​​ on rails

Collection.Contains() 使用啥来检查现有对象?

在创建新实体之前检查现有实体

在 Ruby on Rails 中检查视图中的 nil

rails check_box_tag 使用默认值设置检查