[英]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_tags
和all_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 如果是这种情况,你应该尝试断言这种东西
I would try to do it top down. 我会尝试自上而下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.