Ruby on rails Rails应用程序中的虚拟属性-为什么attr_writer不让我的输入使用getter和setter方法?

Ruby on rails Rails应用程序中的虚拟属性-为什么attr_writer不让我的输入使用getter和setter方法?,ruby-on-rails,ruby-on-rails-3,attr-accessible,virtual-attribute,Ruby On Rails,Ruby On Rails 3,Attr Accessible,Virtual Attribute,我正在尝试推出自己的标签系统。我的设置(目前)非常类似于acts_as_taggable_on,带有标记、标记对象和标记,以将一个与另一个关联起来。Taggable是一个模块,它将包含在事件、用户以及其他一些类型的可标记对象中。目前我只是想把它和事件联系起来 我跟在后面 在railscast中,可通过attr\u writer:tag\u names访问虚拟属性tag\u names 我的问题是,除非我使用attr\u accessible:tag\u names(即“attr\u access

我正在尝试推出自己的标签系统。我的设置(目前)非常类似于acts_as_taggable_on,带有标记、标记对象和标记,以将一个与另一个关联起来。Taggable是一个模块,它将包含在事件、用户以及其他一些类型的可标记对象中。目前我只是想把它和事件联系起来

我跟在后面

在railscast中,可通过
attr\u writer:tag\u names
访问虚拟属性tag\u names

我的问题是,除非我使用
attr\u accessible:tag\u names
(即“attr\u accessible”而不是“attr\u writer”),否则我无法让tag\u names字段接受输入

当指定
attr\u writer:tag\u names
时,我提交表单并得到错误:“无法批量分配受保护的属性:tag\u names”。当我把
attr\u accessible:tag\u names
放在这里时,它似乎工作正常,但这是一个安全问题,对吗?(请注意:数据库中没有用于事件对象的标记名称字段。)

为什么我不能复制Railscast?我运行的是Rails 3.2.11,Railscast是从2009年开始的,但我找不到任何迹象表明attr_writer已经被attr_所取代,在这个更高版本或类似的版本中,attr_是可以访问的

谢谢你的帮助

我的活动表格的相关部分:

<%= f.input :tag_names, label: "Tags (separate by commas)" %>

attr\u accessible
attr\u writer
是两件完全不同的事情。前者是Rails 4之前的一个概念,您可以在其中白名单上列出可大规模分配的属性。后者是在类上创建一个实例方法,允许您公开设置一个值,但不能读取它

还有
attr\u读取器
attr\u访问器


attr\u accessor
可能是您混淆的
attr\u accessible
。此方法类似于
attr\u writer
,只是它同时提供了reader和writer方法
attr\u reader
attr\u writer
相反,它为您提供了一个读取值而不是写入值的实例方法。

谢谢。问题是,我已经尝试了你提到的几乎所有东西(attr_writer和attr_accessor以及attr_accessible)。Railscast说使用“attr_writer”,这是我第一次尝试的,但出现了一个错误。我能绕过这个错误的唯一方法(“不能批量分配受保护的属性:标记名称”)似乎是包含“attr\u可访问:标记名称”。我知道这是错误的。标记名甚至不是我数据库中的一个字段。我只想能够提交表单,让setter方法在字段中使用逗号分隔的标记来创建多个标记对象。希望这是有意义的?刚刚发现看起来在同一个铁路司机之后也遇到了同样的问题。他似乎很高兴,但我不知道他做了什么来解决这个问题!这可能与simple_表单处理虚拟属性的方式有关。。。
class Event < ActiveRecord::Base
    include Taggable

    # Default - order by start time
    default_scope :order => 'events.start_time ASC'

    belongs_to :creator, :foreign_key => "creator_id", :class_name => "User"
    validates_presence_of :creator

    (etc)
module Taggable
    extend ActiveSupport::Concern

    included do
        has_many :taggings, :as => :taggable
        has_many :tags, :through => :taggings

        attr_accessible :tag_names
    end

    def tag(name)
        name.strip!
        tag = Tag.find_or_create_by_name(name)
        self.taggings.find_or_create_by_tag_id(tag.id)
    end

    def untag(name)
        name.strip!
        t = Tag.find_by_name(name)
        self.taggings.find_by_tag_id(t).destroy
    end

    # Return an array of tags applied to this taggable object
    def tag_list
       Tag.joins(:taggings).where(taggings: {taggable_id: self})
    end

   # Getter method for virtual attribute tag_names
   def tag_names
       @tag_names || tags.map(&:name).join(', ')
   end

   # Setter method for virtual attribute tag_names
   def tag_names=(names)
       @tag_names = names.split(",").map do |n|
           Tag.find_or_create_by_name(n.strip)
       end
   end  
end