I want to be able to create a record in the DB but then prevent Rails from making changes from that point on. I understand changes will still be possible at the DB level.
我希望能够在DB中创建一个记录,但是这样就可以防止Rails从那时起进行更改。我知道在DB级别上仍然可以进行更改。
I believe attr_readonly does what I want on an attribute level, but I don't want to have to manually specify fields... I would rather have more of a white-list approach.
我相信attr_readonly在属性级别上做了我想做的事情,但是我不想手工指定字段……我宁愿有更多的白名单。
Also, I know there is a :read_only option for associations, but I don't want to limit the "readonlyness" of the object to if it was fetched via an association or not.
另外,我知道有一个:read_only选项用于关联,但是我不想限制对象的“readonlyness”,如果它是通过关联来获取的。
Finally, I want to be able to still destroy a record so stuff like :dependent => :destroy works in the associations.
最后,我希望仍然能够销毁一个记录,比如:dependency =>:destroy works in the associations。
So, to summarize: 1) allow the creation of records, 2) allow the deletion of records, and 3) prevent changing records that have been persisted.
因此,总结:1)允许创建记录,2)允许删除记录,3)防止更改保存的记录。
7 个解决方案
#1
70
Looking at ActiveRecord::Persistence
, everything ends up calling create_or_update
behind the scenes.
查看ActiveRecord::持久性,所有东西都在后台调用create_or_update。
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : update
result != false
end
So! Just:
如此!只是:
def readonly?
!new_record?
end
#2
37
I've found a more concise solution, which uses the after_initialize
callback:
我找到了一个更简洁的解决方案,它使用after_initialize回调:
class Post < ActiveRecord::Base
after_initialize :readonly!
end
#3
25
Why not just create a user on the database that has read only access, and have rails use that account.
为什么不直接在数据库上创建一个只有读权限的用户,并让rails使用这个帐户呢?
However if you want model level access, you can add the following to a specific model:
但是,如果您想要模型级别的访问,您可以在特定的模型中添加以下内容:
def readonly?
true
end
def before_destroy
raise ActiveRecord::ReadOnlyRecord
end
#4
13
This blog post is still valid: http://ariejan.net/2008/08/17/activerecord-read-only-models/
这篇博文仍然有效:http://ariejan.net/2008/08/17/activerecord- read-onmodels/
Basically you can rely on ActiveRecord's validation if you add a method:
基本上,如果你添加一个方法,你可以依赖ActiveRecord的验证:
def readonly?
true
end
#5
4
TL;DR for OP's
class YourModel < ActiveRecord::Base
before_save { false } # prevent create & update, allows destroy
# ...
end
Generally
- To prevent creates only:
before_create { false }
- 要防止只创建:before_create {false}
- To prevent updates only:
before_update { false }
- 仅防止更新:before_update {false}
- To prevent destroys only:
before_destroy { false } # does not prevent delete
- 要防止仅破坏:before_destroy {false} #不阻止删除
See also: http://guides.rubyonrails.org/active_record_callbacks.html
参见:http://guides.rubyonrails.org/active_record_callbacks.html
#6
1
This seems to be fairly effective and is probably a bit overkill, but for my case, I really want to be sure my application will never create, save, update, or destroy any records in the model, ever.
这似乎相当有效,而且可能有点过了头,但对于我来说,我真的希望确保我的应用程序永远不会创建、保存、更新或销毁模型中的任何记录。
module ReadOnlyModel
def readonly?() true end
def create_or_update() raise ActiveRecord::ReadOnlyRecord end
before_create { raise ActiveRecord::ReadOnlyRecord }
before_destroy { raise ActiveRecord::ReadOnlyRecord }
before_save { raise ActiveRecord::ReadOnlyRecord }
before_update { raise ActiveRecord::ReadOnlyRecord }
end
class MyModel < ActiveRecord::Base
include ReadOnlyModel
# ...
end
Since OP asked to be able to create and destroy but not save or update I believe this will work
由于OP要求能够创建和销毁,但不能保存或更新,我相信这将有效
module SaveAndDestroyOnlyModel
before_save { raise ActiveRecord::ReadOnlyRecord }
before_update { raise ActiveRecord::ReadOnlyRecord }
end
class MyModel < ActiveRecord::Base
include SaveAndDestroyOnlyModel
# ...
end
Not exactly the right exception, but close enough I think.
不完全是正确的例外,但我认为已经足够接近了。
#7
0
A custom validator can do this:
一个自定义验证器可以这样做:
validate :nothing_changed, unless: :new_record? # make immutable
...
def nothing_changed
errors.add(:base, "Record is read-only") if self.changed?
end
#1
70
Looking at ActiveRecord::Persistence
, everything ends up calling create_or_update
behind the scenes.
查看ActiveRecord::持久性,所有东西都在后台调用create_or_update。
def create_or_update
raise ReadOnlyRecord if readonly?
result = new_record? ? create : update
result != false
end
So! Just:
如此!只是:
def readonly?
!new_record?
end
#2
37
I've found a more concise solution, which uses the after_initialize
callback:
我找到了一个更简洁的解决方案,它使用after_initialize回调:
class Post < ActiveRecord::Base
after_initialize :readonly!
end
#3
25
Why not just create a user on the database that has read only access, and have rails use that account.
为什么不直接在数据库上创建一个只有读权限的用户,并让rails使用这个帐户呢?
However if you want model level access, you can add the following to a specific model:
但是,如果您想要模型级别的访问,您可以在特定的模型中添加以下内容:
def readonly?
true
end
def before_destroy
raise ActiveRecord::ReadOnlyRecord
end
#4
13
This blog post is still valid: http://ariejan.net/2008/08/17/activerecord-read-only-models/
这篇博文仍然有效:http://ariejan.net/2008/08/17/activerecord- read-onmodels/
Basically you can rely on ActiveRecord's validation if you add a method:
基本上,如果你添加一个方法,你可以依赖ActiveRecord的验证:
def readonly?
true
end
#5
4
TL;DR for OP's
class YourModel < ActiveRecord::Base
before_save { false } # prevent create & update, allows destroy
# ...
end
Generally
- To prevent creates only:
before_create { false }
- 要防止只创建:before_create {false}
- To prevent updates only:
before_update { false }
- 仅防止更新:before_update {false}
- To prevent destroys only:
before_destroy { false } # does not prevent delete
- 要防止仅破坏:before_destroy {false} #不阻止删除
See also: http://guides.rubyonrails.org/active_record_callbacks.html
参见:http://guides.rubyonrails.org/active_record_callbacks.html
#6
1
This seems to be fairly effective and is probably a bit overkill, but for my case, I really want to be sure my application will never create, save, update, or destroy any records in the model, ever.
这似乎相当有效,而且可能有点过了头,但对于我来说,我真的希望确保我的应用程序永远不会创建、保存、更新或销毁模型中的任何记录。
module ReadOnlyModel
def readonly?() true end
def create_or_update() raise ActiveRecord::ReadOnlyRecord end
before_create { raise ActiveRecord::ReadOnlyRecord }
before_destroy { raise ActiveRecord::ReadOnlyRecord }
before_save { raise ActiveRecord::ReadOnlyRecord }
before_update { raise ActiveRecord::ReadOnlyRecord }
end
class MyModel < ActiveRecord::Base
include ReadOnlyModel
# ...
end
Since OP asked to be able to create and destroy but not save or update I believe this will work
由于OP要求能够创建和销毁,但不能保存或更新,我相信这将有效
module SaveAndDestroyOnlyModel
before_save { raise ActiveRecord::ReadOnlyRecord }
before_update { raise ActiveRecord::ReadOnlyRecord }
end
class MyModel < ActiveRecord::Base
include SaveAndDestroyOnlyModel
# ...
end
Not exactly the right exception, but close enough I think.
不完全是正确的例外,但我认为已经足够接近了。
#7
0
A custom validator can do this:
一个自定义验证器可以这样做:
validate :nothing_changed, unless: :new_record? # make immutable
...
def nothing_changed
errors.add(:base, "Record is read-only") if self.changed?
end