问题描述
我正在尝试实现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提交中读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!