方法与属性Rails

时间:2015-01-15 04:02:08

标签: ruby-on-rails ruby

今晚与我的一位同事就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”,对吗?用户的first_name属性与名为“first_name”的方法不同。因此,名为“first_name”的用户对象上的属性与Rails中名为“first_name”的用户类上的方法不同,对吗?这就像一个类级方法vs一个实例方法?只是想确定我是正确的,我正确地解释了这一点。

感谢

- 麦克

3 个答案:

答案 0 :(得分: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,它就会从中重构它name。一个更常见的模式是将名称设置为类似ensure_first_name的方法(基本上任何不与getter同类的东西)

实例变量(例如@foo)与同名方法不同,尽管foofoo=通常用于获取/设置实例变量的方法名称。也许你在考虑那个?在某种情况下,Activerecord模型的属性不会存储在单个实例变量中。

答案 1 :(得分:0)

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

例如,使用用户模型,用户控制器及其相应的视图之一。让我们假设用户模型本身包含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}!"

但我们也可以在视图中调用User 方法。继续我们的最后一个例子,我们可以添加这样的东西:

####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!'

简而言之,你是正确的,属性和方法是非常不同的,虽然它们有时看起来很相似。

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

希望这有帮助!

答案 2 :(得分:0)

是的,你解释的是正确的。 您的编码将起作用并分配first_name&amp; 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