Chr*_*fer 5 ruby-on-rails nested-forms has-and-belongs-to-many
使用 Rails 4.1.13 和 Ruby 2.0.0(虽然我在使用 Ralis 4.0 和 Ruby 1.9.3 时遇到了同样的问题。我已经阅读了许多关于这个特定问题的文章,但无法理解为什么我的解决方案(看起来完全像这样)没有工作,所以请帮助我。
我有两个模型 BlogPost 和 Tag。一个博客帖子可以有多个标签,一个标签可以有多个博客帖子。我通过第三个模型 BlogPostRelation 将它们连接起来。因此,这是我的基本设置:
# blog_post.rb
has_many :blog_post_tag_relations, dependent: :destroy
has_many :tags, :through => :blog_post_tag_relations
accepts_nested_attributes_for :blog_post_tag_relations, :tags
# tag.rb
has_many :blog_post_tag_relations, dependent: :destroy
has_many :blog_posts, :through => :blog_post_tag_relations
# blog_post_tag_relation.rb
belongs_to :tag
belongs_to :blog_post
validates_uniqueness_of :tag_id, :scope => [:blog_post_id]
validates :blog_post_id, :presence => true
validates :tag_id, :presence => true
accepts_nested_attributes_for :tag, :blog_post
Run Code Online (Sandbox Code Playgroud)
我有一个使用 Formtastic 的 BlogPost 表单,我在其中使用以下命令为 BlogPost 创建复选框:
<%= f.input :blog_title %>
<%= f.input :tags, as: :check_boxes, :collection => tags.order(:name) %>
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是在添加标签之前没有保存 BlogPost,这导致 blog_post_id 不存在(它不是)的验证失败:
Tag Load (1.6ms) SELECT "tags".* FROM "tags" WHERE "tags"."id" IN (678, 56)
(0.9ms) BEGIN
BlogPost Exists (1.6ms) SELECT 1 AS one FROM "blog_posts" WHERE ("blog_posts"."id" IS NOT NULL) AND "blog_posts"."slug" = 'de22323' LIMIT 1
BlogPostTagRelation Exists (1.2ms) SELECT 1 AS one FROM "blog_post_tag_relations" WHERE ("blog_post_tag_relations"."tag_id" = 678 AND "blog_post_tag_relations"."blog_post_id" IS NULL) LIMIT 1
CACHE (0.0ms) SELECT 1 AS one FROM "blog_posts" WHERE ("blog_posts"."id" IS NOT NULL) AND "blog_posts"."slug" = 'de22323' LIMIT 1
BlogPostTagRelation Exists (1.1ms) SELECT 1 AS one FROM "blog_post_tag_relations" WHERE ("blog_post_tag_relations"."tag_id" = 56 AND "blog_post_tag_relations"."blog_post_id" IS NULL) LIMIT 1
CACHE (0.0ms) SELECT 1 AS one FROM "blog_posts" WHERE ("blog_posts"."id" IS NOT NULL) AND "blog_posts"."slug" = 'de22323' LIMIT 1
(0.8ms) ROLLBACK
Run Code Online (Sandbox Code Playgroud)
似乎解决方案应该是使用inverse_of,坦率地说,我不理解 100%。还应该提到的是,我不是 100% 确定如何将accepts_nested_attributes_for两者用于此类问题。我已经尝试了所有不同的设置,但据我所知,它们应该在连接模型中的唯一位置,BlogPostRelation,如下所示:
# blog_post_tag_relation.rb
belongs_to :tag, :inverse_of => :blog_post_tag_relations
belongs_to :blog_post, :inverse_of => :blog_post_tag_relations
validates_uniqueness_of :tag_id, :scope => [:blog_post_id]
validates :blog_post_id, :presence => true
validates :tag_id, :presence => true
accepts_nested_attributes_for :tag, :blog_post
Run Code Online (Sandbox Code Playgroud)
这也不起作用,我现在完全不知道该怎么做。
这里的部分问题是您正在验证 ids。如果 id 未知,Rails 无法验证 blog_post_id 是否存在,但它可以验证 blog_post 是否存在。
因此,至少部分答案是验证关联实例的存在,而不是 id。
将验证更改为:
validates :blog_post, :presence => true
validates :tag , :presence => true
Run Code Online (Sandbox Code Playgroud)
我总是会指定 inverse_of ,但我不确定它是这个问题的一部分。
| 归档时间: |
|
| 查看次数: |
747 次 |
| 最近记录: |