0

Я пытаюсь свернуть свою собственную систему тегов. Моя настройка (на данный момент) очень похожа на act_as_taggable_on, с тегами, объектами Taggable и Taggings, чтобы связать их друг с другом. Taggable - это модуль, который будет включен в Events, Users и, возможно, несколько других видов объектов, которые будут taggable. На данный момент я просто пытаюсь подключить его к работе с Events.Виртуальный атрибут в приложении Rails - почему attr_writer не делает мой ввод работы с моими методами getter и setter?

Я следую за Railscast #167.

В railscast виртуальный атрибут tag_names становится доступным с attr_writer :tag_names.

Моя проблема заключается в том, что я не могу получить поле tag_names для ввода ввода, если я не использую attr_accessible :tag_names (т. Е. 'Attr_accessible' вместо 'attr_writer').

при указании attr_writer :tag_names, я отправляю форму и получаю сообщение об ошибке: «Невозможно назначить защищенные атрибуты: tag_names». Когда я ставлю attr_accessible :tag_names, это похоже на работу, но это проблема безопасности, верно? (Обратите внимание: там не поле tag_names в БД для объектов Event.)

И почему я не могу реплицировать Railscast? Я запускаю Rails 3.2.11, а Railscast - с 2009 года, но я ничего не могу найти, говоря, что attr_writer был заменен attr_accessible в этой более поздней версии или что-то в этом роде.

Спасибо за помощь!

Соответствующая часть моей формы проведения:

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

Моя модель событий:

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) 

Мой Taggable модуль:

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 

ответ

2

attr_accessible и attr_writer две совершенно разные вещи. Первый представляет собой концепцию pre-Rails 4, где вы являетесь атрибутами whitelisting, которые могут быть назначены по массе. Последний создает метод экземпляра в вашем классе, который позволяет публиковать значение, но не читать его.

Есть также attr_reader и attr_accessor.

attr_accessor Возможно, вы смущаетесь с attr_accessible. Этот метод аналогичен attr_writer, за исключением того, что он обеспечивает как метод чтения, так и записи. attr_reader - это противоположность attr_writer тем, что он дает вам метод экземпляра для чтения значений, но не записывает их.

+0

Спасибо. Дело в том, что я пробовал почти все, что вы упоминаете (attr_writer и attr_accessor, а также attr_accessible). Railscast говорит использовать «attr_writer», и это то, что я пробовал в первую очередь, но получил ошибку. Единственный способ обойти ошибку («Нельзя назначать защищенные атрибуты: tag_names»), похоже, включать «attr_accessible: tag_names». Я знаю, что это неправильно. tag_names не является даже полем в моей базе данных. Я просто хочу, чтобы иметь возможность отправить форму и метод setter использовать теги, разделенные запятыми, в поле для создания нескольких объектов Tag. Надеюсь, что это имеет смысл? – Reb

+0

Просто обнаружил, что [этот человек] (http://stackoverflow.com/questions/8772498/rails-virtual-attributes-wont-read-from-form-for-submission?rq=1), похоже, испытал ту же проблему после того же railscast.Кажется, он оказался счастливым, но я не могу понять, что он сделал, чтобы исправить это! – Reb

+0

Возможно, это проблема, связанная с тем, как simple_form обрабатывает виртуальные атрибуты ... – Reb