0

我真的对 Rails 3.2 中的虚拟属性感到困惑,我所有的研究都无助于让事情变得更清晰。

# input model
class Input < ActiveRecord::Base

  # Attributes --------------------
  attr_accessible :title, :parent
  attr_accessor :parent

  def parent=(id)
    wrtite_attribute(:parent, id.to_i)
    self.parent = id.to_i
    self[:parent] = id.to_i
    @parent = id.to_i # seems to be the only one working. Why?
  end

end

# inputs controller
class InputsController < ApplicationController

  def new
    @input = Input.new({
      start_date: @current_scope_company.creation_date,
      parent: 'bla'
    })

    @input.parent = 'bla'
    @input[;parent] = 'bla'

  end
end

# inputs table
create_table "inputs", :force => true do |t|
  t.string   "title"
  t.datetime "created_at",                        :null => false
  t.datetime "updated_at",                        :null => false
end

以上,我已经编译了我在互联网上找到的几乎所有替代品。这不是我运行的代码,只是同一事物的几个版本。虽然,无论我尝试什么,我都会收到以下警告:

DEPRECATION WARNING: You're trying to create an attribute 'parent'. Writing arbitrary attributes on a model is deprecated. Please just use 'attr_writer' etc.

有时,我什至得到一个stack level too deep. 我很想了解属性是如何工作的。

1/attr_accessorattr_writerattr_reader对吗?为什么要求我attr_writer在警告中使用?

2/ 我应该如何从模型中写入属性(以及为什么)

3/ 我应该如何从控制器中写入属性(以及为什么)

非常感谢!

更新

经过进一步测试,看起来正确的方法是@parent = id.to_i。我仍然很想解释为什么。我真的很困惑为什么self.不工作。

4

1 回答 1

1

Atttr_accessor 应该没问题。所以在你的模型中,看起来你正试图以四种不同的方式做同样的事情:

def parent=(id)
  write_attribute(:parent, id.to_i)
  self.parent = id.to_i
  self[:parent] = id.to_i
  @parent = id.to_i            # <- all these are redundant and scary
end

(此外,在您的控制器中,您似乎也在尝试以不同的方式做同样的事情,这是不必要的。)此外,我很确定语法 'def parent=(id)' 仅适用于真实属性。查看此 railscast并根据我自己的经验,您只需为虚拟属性执行以下操作:

def parent
  @id.to_i
end

“id”来自哪里,应该进入“父母”?虚拟属性必须以某种方式与实际存储在数据库中的东西相关联,无论是通过真实属性还是通过关联的真实属性。如果您解释更多实际应该计算父母的内容,那么会更容易提供帮助。

于 2013-11-23T01:29:28.863 回答