简体   繁体   English

rails:has_many association:验证对数组的访问的最佳实践

[英]rails: has_many association: best practices to validate access to array

I'm pretty new to ruby and ruby-on-rails, so I need to learn best practices. 我对ruby和ruby-on-rails很新,所以我需要学习最佳实践。

I have Tag model, each tag can have many sub-tags and many super-tags: 我有Tag模型,每个标签可以有很多子标签和许多超级标签:

  has_many :super_tags, :through => :tag_hier_rels,         :source => :super_tag
  has_many :sub_tags,   :through => :reverse_tag_hier_rels, :source => :sub_tag

  has_many :tag_hier_rels,         :foreign_key => "sub_tag_id"
  has_many :reverse_tag_hier_rels, :foreign_key => "super_tag_id", :class_name => "TagHierRel"

I need to prevent user to create circular references. 我需要阻止用户创建循环引用。 But with auto-generated methods :super_tags and :sub_tags I can't do this: everyone can do something like: 但是使用自动生成的方法:super_tags:sub_tags我不能这样做:每个人都可以这样做:

tag.super_tags.push another_tag , and I have no control on this. tag.super_tags.push another_tag ,我对此无法控制。 Rails validation mechanism isn't useful here: this mechanism prevents user to save invalid objects to database, but I need to prevent him even to modify object incorrectly: if I have circular reference, and I need to get all the sub-tags or super-tags recursively, I will run into stack overflow. Rails验证机制在这里没用:这个机制阻止用户将无效对象保存到数据库,但我需要阻止他甚至错误地修改对象:如果我有循环引用,我需要获取所有子标签或超级-tags递归,我将遇到堆栈溢出。

So I have done the following: 所以我做了以下事情:

Declared these associations as private ones: 将这些关联声明为私有关联:

private :sub_tags=,   :sub_tags
private :super_tags=, :super_tags

Added methods with _copy postfix: 使用_copy后缀添加方法:

def sub_tags_copy
  return sub_tags.clone
end

def super_tags_copy
  return super_tags.clone
end

And added methods that actualy modify arrays: 并添加了实际修改数组的方法:

  def sub_tags_push(tag)
    sub_tags.push tag if !self.all_sub_tags.include? tag and !self.all_super_tags.include? tag
  end

  def super_tags_push(tag)
    super_tags.push tag if !self.all_sub_tags.include? tag and !self.all_super_tags.include? tag
  end

  # TODO: more methods (at least we need to remove tags)

(methods all_sub_tags and all_super_tags generate arrays recursively) (方法all_sub_tagsall_super_tags递归生成数组)

It works, but I don't really like this solution: at least, it's not obvious for user that he should use ..._copy methods. 它有效,但我并不喜欢这个解决方案:至少,用户不应该使用... ..._copy方法。

Probably I am doing this wrong? 可能我这样做错了?

UPD: UPD:

Or, is it bad practice in general to disallow user to change an object in wrong way? 或者,一般来说不允许用户以错误的方式更改对象是不好的做法? Probably I should allow user to change an object in wrong way, but only validate it before saving? 可能我应该允许用户以错误的方式更改对象,但只在保存之前验证它?

At least, I already figured out that it's hard to supply error messages if user does something wrong: currently, model just silently does not modify an object, and no error message is generated. 至少,我已经发现,如果用户做错了,很难提供错误消息:目前,模型只是默默地不修改对象,并且不会生成错误消息。 I have to implement my own error messages engine, and this fact is an evidence that approach is really bad... I seem to struggle against the framework instead of using it. 我必须实现我自己的错误消息引擎,这个事实证明方法真的很糟糕......我似乎在反对框架而不是使用它。

You are always referring to user where you mean programmers ? 你总是指user你的意思是programmers

If that is the case, you should try to assert this kind of stuff through 如果是这种情况,你应该尝试断言这种东西

  1. Education (developer to developer) 教育(开发人员)
  2. Validation (via tests or rails validations) 验证(通过测试或rails验证)
  3. Constraints (on the database level through db constraints or triggers) 约束(通过数据库约束或触发器在数据库级别上)

I would try to do it top down. 我会尝试自上而下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM