【问题标题】:Methods vs Attributes Rails方法与属性 Rails
【发布时间】:2015-01-15 04:02:08
【问题描述】:

今晚与我的一位同事就 Rails 中的方法与属性进行了辩论。我发誓我以前见过这个,除非我疯了。这是一个例子:

我们有一个用户模型,我们希望在保存记录之前确定我们有名字和姓氏。我讨厌回调,但对于这个例子,假设它在 before_save 回调中。

class User     
  before_save :set_first_last

  def set_first_last
    first_name if self.first_name.blank?
    last_name if self.last_name.blank?
  end

  def first_name
    self.first_name = self.name.split(" ").first
  end

  def last_name
    self.last_name = self.name.split(" ").last
  end
end

所以,我很好奇是否调用了方法“set_first_last”名称并且它看到用户上的属性 first_name 是空白的,它会调用方法“first_name”,对吗? user 上的属性 first_name 与称为“first_name”的方法不同。因此,名为“first_name”的用户对象上的属性与 Rails 中名为“first_name”的用户类上的方法不同,对吗?这就像类级方法与实例方法?只是想确保我是正确的,并且我正在正确地解释这一点。

谢谢

--麦克

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    我认为您误读了这段代码:

    def set_first_last
      first_name if self.first_name.blank?
      last_name if self.last_name.blank?
    end
    

    这段代码调用first_name方法,如果为空则再次调用first_name方法(也就是说该方法的if部分没有意义)

    这段代码的构造方式,永远不会使用 first_name 和 last_name 属性的值(除非您在查询中使用它们) - 任何时候你这样做 user.first_name 它都会从 @987654326 重建它@。更常见的模式是将设置名称的方法称为 ensure_first_name (基本上任何不与 getter 分类的东西)

    实例变量(例如@foo)不同于同名的方法,尽管foofoo= 作为获取/设置同名实例变量的方法当然很常见。也许你是这么想的?如果 Activerecord 模型的属性没有存储在单个实例变量中。

    【讨论】:

      【解决方案2】:

      回答我认为我理解的部分:是的,模型上的属性与方法完全不同。

      以一个用户模型、一个用户控制器及其对应的视图之一为例。假设 User 模型本身包含 first_namelast_nameemail 属性:

      class User < ActiveRecord::Base
        #Ensure presence of the following before saving model
        validates_presence_of :first_name, :last_name, :email 
      
        #Verify unique email
        validates_uniqueness_of :email
      
        #Here's our lone User method...poor guy
        def admin?
          self.company_members.where('? = ANY (company_members.roles)', Role::ADMIN).any?
        end
      end
      

      当您开始在控制器中使用该模型的 实例 时,它看起来像这样:

      class UsersController < ApplicationController
        def index
          #Let's just grab a random user
          @user = User.find(1)
        end
      end
      

      最后,在您看来,您的属性(属性)可以通过以下方式访问:

      ####views/users/index.html.haml####
      
      .random-class
        = "You're logged in as #{@user.first_name}!"
      

      但我们也可以在视图中调用用户方法。继续上一个示例,我们可以添加如下内容:

      ####views/users/index.html.haml####
      
      .random-class
        = "You're logged in as #{@user.first_name}!"
        - if @user.admin?
          = 'Oh my gosh, our freaking User method worked!'
      

      因此,简而言之,您说得对,因为属性和方法非常不同,尽管它们有时看起来很相似。

      最后,值得指出的是,实例方法就是:在类的instances上调用方法,而在实际模型对象上调用类方法,以及不是该模型对象的单个实例。 Here's a great link to learn more about the differences.

      希望这会有所帮助!

      【讨论】:

      • 当您执行 @user.first_name 时,您肯定会调用一个名为 first_name 的方法(然后调用 read_attribute)
      • 你说得对,弗雷德里克。不过,我试图将其归结为蹩脚的术语,而不必解释发生的整个过程堆栈。我认为迈克只是在寻找快速验证。不过,感谢您的进一步澄清。
      【解决方案3】:

      是的,你的解释是正确的。 您的一段编码将起作用,并使用拆分形式分配 first_name 和 last_name。 此外,您也可以用这种方式编写代码(假设您的全名由空格分隔的 2 个单词组成)

       #user.rb
      class user     
        before_save :assign_individual_names
      
       private 
        def assign_individual_names
          first_name, last_name = name.split(' ')
        end
      
      end
      

      【讨论】:

        猜你喜欢
        • 2017-07-16
        • 1970-01-01
        • 2012-05-05
        • 2014-08-18
        • 2017-11-09
        • 2011-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多