Rails虚拟属性不会从form_for提交中读取 [英] rails virtual attributes won't read from form_for submission

查看:89
本文介绍了Rails虚拟属性不会从form_for提交中读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现Ryan Bate的railscast#167中概述的rails标记模型. http://railscasts.com/episodes/167-more-on-virtual-attributes

I am trying to implement a rails tagging model as outlined in Ryan Bate's railscast #167. http://railscasts.com/episodes/167-more-on-virtual-attributes

这是一个很棒的系统.但是,我无法获得将tag_names提交给控制器的表单. tag_names的定义是:

This is a great system to use. However, I cannot get the form to submit the tag_names to the controller. The definition for tag_names is :

 def tag_names
   @tag_names || tags.map(&:name).join(' ')
 end

不幸的是,在我的情况下,@ tag_names从未在表单提交时分配.我不知道为什么.因此,它始终默认为tag.map(&:name).join('').这意味着我无法创建Articles,因为它们的tag_name不存在,并且我也无法在现有标签上编辑这些标签.有人可以帮忙吗?

Unfortunately, @tag_names never gets assigned on form submission in my case. I cannot figure out why. SO it always defaults to tags.map(&:name).join(' '). This means that I can't create Articles because their tag_names are not there, and I also can't edit these tags on existing ones. Anyone can help?

推荐答案

简而言之,您的课程缺少一个setter(或者在Ruby lingo中,一个属性编写器).您可以通过两种方式定义设置器,并处理将以空格分隔的标签名称的字符串转换为Tag对象并将其保存在数据库中的方法.

In short, your class is missing a setter (or in Ruby lingo, an attribute writer). There are two ways in which you can define a setter and handle converting the string of space-separated tag names into Tag objects and persist them in the database.

在您的类中,使用Ruby的attr_writer方法定义您的setter并将标记名称的字符串(例如"tag1 tag2 tag3")转换为Tag对象,然后在after save回调中将它们保存在数据库中.您还需要一个吸气剂,用于将文章的Tag对象数组转换为字符串表示形式,其中标记由空格分隔:

In your class, define your setter using Ruby's attr_writer method and convert the string of tag names (e.g. "tag1 tag2 tag3") to Tag objects and save them in the database in an after save callback. You will also need a getter that converts the array of Tag object for the article into a string representation in which tags are separated by spaces:

class Article << ActiveRecord::Base
  # here we are delcaring the setter
  attr_writer :tag_names

  # here we are asking rails to run the assign_tags method after
  # we save the Article
  after_save :assign_tags

  def tag_names
    @tag_names || tags.map(&:name).join(' ')
  end

  private

  def assign_tags
    if @tag_names
      self.tags = @tag_names.split(/\s+/).map do |name|
        Tag.find_or_create_by_name(name)
      end
    end
  end
end

解决方案2:将标记名称的字符串转换为setter中的Tag个对象

Solution 2: Converting the string of tag names to Tag objects in the setter

class Article << ActiveRecord::Base
  # notice that we are no longer using the after save callback
  # instead, using :autosave => true, we are asking Rails to save
  # the tags for this article when we save the article
  has_many :tags, :through => :taggings, :autosave => true

  # notice that we are no longer using attr_writer
  # and instead we are providing our own setter
  def tag_names=(names)
     self.tags.clear
     names.split(/\s+/).each do |name|
       self.tags.build(:name => name)
     end
  end

  def tag_names
    tags.map(&:name).join(' ')
  end
end

这篇关于Rails虚拟属性不会从form_for提交中读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆