加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 由于id = null,Rails has_many无法以嵌套形式

发布时间:2020-12-17 02:48:48 所属栏目:百科 来源:网络整理
导读:使用Rails 4.1.13和 Ruby 2.0.0(虽然我在Ralis 4.0和Ruby 1.9.3上遇到了同样的问题.我已经阅读了很多关于这个特定问题的文章,并且无法理解为什么我的解决方案(看起来与 this完全一样)没有工作,所以请帮帮我. 我有两个模型BlogPost和Tag. BlogPost可以包含许
使用Rails 4.1.13和 Ruby 2.0.0(虽然我在Ralis 4.0和Ruby 1.9.3上遇到了同样的问题.我已经阅读了很多关于这个特定问题的文章,并且无法理解为什么我的解决方案(看起来与 this完全一样)没有工作,所以请帮帮我.

我有两个模型BlogPost和Tag. BlogPost可以包含许多标签,一个标签可以包含许多BlogPost.我通过第三个模型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

我有一个BlogPost表单,使用Formtastic,我使用以下方法为BlogPost创建复选框:

<%= f.input :blog_title %>
<%= f.input :tags,as: :check_boxes,:collection => tags.order(:name) %>

我遇到的问题是在添加标签之前没有保存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

似乎解决方案应该是使用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,:presence => true    

accepts_nested_attributes_for :tag,:blog_post

这也不起作用,我现在完全迷失了.

>最重要的是:我该怎么办?
>这个问题的解决方案是inverse_of吗?如果是这样,我应该如何使用它?
>我正确使用accepts_nested_attributes_for吗?
>它是否与BlogPostTagRelation的命名有关(它应该被称为BlogPostTag吗?

解决方法

这里的部分问题是您正在验证ID.如果id未知,则Rails无法验证blog_post_id是否存在,但它可以验证blog_post是否存在.

因此,答案的一部分至少是验证相关实例的存在,而不是id.

将验证更改为:

validates :blog_post,:presence => true
validates :tag,:presence => true

我也总是指定inverse_of,但我不确定它是否是这个问题的一部分.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读