不久前我问了一个关于选择选项的类似问题,但我似乎仍然无法理解它。我对 Rails 很陌生,但这就是我想要做的
我有一个 Post 表,其中有一个“ post_status ”列。我想给每个帖子 3 个选项:
- 草稿
- 待办的
- 发布
我将如何在 Rails 中创建这 3 个选项? (我被建议不要为此使用布尔值)
先感谢您
不久前我问了一个关于选择选项的类似问题,但我似乎仍然无法理解它。我对 Rails 很陌生,但这就是我想要做的
我有一个 Post 表,其中有一个“ post_status ”列。我想给每个帖子 3 个选项:
- 草稿
- 待办的
- 发布
我将如何在 Rails 中创建这 3 个选项? (我被建议不要为此使用布尔值)
先感谢您
在这个特定的例子中,它们看起来像可以通过几种方式处理的状态标志,但是您已经询问了选择选项,所以这里是该方法的解决方案。
因为您没有指定是否需要保留表中已有的值,所以我详细介绍了一种方法,该方法允许您通过将它们转换为 ID 来保留它们(假设它们当前是字符串),如果这不相关,则仅遵循粗体指示。
创建 PostStatus 资源(模型、迁移、控制器/视图,如果您需要能够更改它们)。
定义关系
PostStatus
has_many :posts
Post
belongs_to :post_status
将值添加到您的 PostStatus 表(如果您有一个带有表中字符串的实时系统,您应该在此处匹配现有的帖子状态字符串以允许您转换数据(详情如下)。
将 Post 表中的列名更改为 post_status_id,将其类型更改为 int。如果这不是实时的,那么只需将列作为整数重做迁移。如果它是一个实时系统,您需要将数据转换为新列,而不仅仅是更改其类型,以下是建议的方法。
add_column :posts, :post_status_id_tmp, :int
Post.reset_column_information # make the new column available to model methods
Post.all.each do |post|
# Assuming you have a string with the option text currently:
post.post_status_id_tmp = PostStatus.find_by_name(post.post_status).id
post.save
end
remove_column :posts, :post_status
rename_column :posts, :post_status_tmp, :post_status_id
在您的帖子表单中添加一个选择框。
<%= form.collection_select :post_status_id, PostStatus.all, :id, :name %>
这至少应该让你开始!
详细说明@Alexander Kobelev 的答案,我会将其全部放入模型中:
class Post < ActiveRecord::Base
STATUS_OPTIONS = {
:draft => 'Draft',
:pending => 'Pending',
:published => 'Published'
}
validates_inclusion_of :post_status, :in => STATUS_OPTIONS.keys
end
在你看来:
帖子状态:<%= select(:post, :post_status, Post::STATUS_OPTIONS.invert) %>
你可以尝试这样的事情:
class Post < ActiveRecord::Base
validates_inclusion_of :status, :in => [:draft, :pending, :publish]
def status
read_attribute(:status).to_sym
end
def status= (value)
write_attribute(:status, value.to_s)
end
end
迁移中的状态为:字符串,限制:20(仅作为示例)