Ruby Rails - Activeadmin - 使用虚拟属性更新模型
Ruby on Rails - Activeadmin - Update model with virtual attribute
我有一个 activeadmin 表单,可以在其中添加 YouTube URL。我在我的视频模型中验证了这个 URL。当我想添加新视频时效果很好,但当我编辑视频时却什么都不做。
app/admin/video.rb :
ActiveAdmin.register Media, as: 'Videos' do
form do |f|
f.inputs "Add youtube video" do
f.input :category
f.semantic_errors :error
f.has_many :videos, allow_destroy: true do |g|
g.input :mylink, :label => "Youtube link : ", :type => :text
end
actions
end
end
end
model/video.rb :
class Video < ApplicationRecord
belongs_to :media
attr_accessor :mylink
YT_LINK_FORMAT = /\A.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*\z/i
before_create :before_add_to_galerie
before_update :before_add_to_galerie
def before_add_to_galerie
uid = @mylink.match(YT_LINK_FORMAT)
self.uid = uid[2] if uid && uid[2]
if self.uid.to_s.length != 11
self.errors.add(:mylink, 'is invalid.')
throw :abort
false
elsif Video.where(uid: self.uid).any?
self.errors.add(:mylink, 'is not unique.')
throw :abort
false
end
end
validates :mylink, presence: true, format: YT_LINK_FORMAT
end
看起来 before_update 方法从未被触发。
我怎样才能让我的编辑工作?
编辑:我发现它正在为媒体模型而不是视频调用 before_update link one.But 创建没问题。
让我尝试重新表述这个问题:
- 你有一个模型
Video
Video
有虚拟属性my_link
Video
有一个 before_update
回调 before_add_to_galerie
- 您希望仅在
my_link
发生更改时触发此回调
这看起来正确吗?
如果是这样,您有 2 个选项,首先 - 如果您有 updated_at
将其与 my_link
一起更改
class Video < ApplicationRecord
attr_reader :my_link
# ...
def my_link=(val)
return val if val == my_link
@my_link = val
self.updated_at = Time.zone.now
end
end
或者您可以使用 ActiveModel
我有一个 activeadmin 表单,可以在其中添加 YouTube URL。我在我的视频模型中验证了这个 URL。当我想添加新视频时效果很好,但当我编辑视频时却什么都不做。
app/admin/video.rb :
ActiveAdmin.register Media, as: 'Videos' do
form do |f|
f.inputs "Add youtube video" do
f.input :category
f.semantic_errors :error
f.has_many :videos, allow_destroy: true do |g|
g.input :mylink, :label => "Youtube link : ", :type => :text
end
actions
end
end
end
model/video.rb :
class Video < ApplicationRecord
belongs_to :media
attr_accessor :mylink
YT_LINK_FORMAT = /\A.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*\z/i
before_create :before_add_to_galerie
before_update :before_add_to_galerie
def before_add_to_galerie
uid = @mylink.match(YT_LINK_FORMAT)
self.uid = uid[2] if uid && uid[2]
if self.uid.to_s.length != 11
self.errors.add(:mylink, 'is invalid.')
throw :abort
false
elsif Video.where(uid: self.uid).any?
self.errors.add(:mylink, 'is not unique.')
throw :abort
false
end
end
validates :mylink, presence: true, format: YT_LINK_FORMAT
end
看起来 before_update 方法从未被触发。
我怎样才能让我的编辑工作?
编辑:我发现它正在为媒体模型而不是视频调用 before_update link one.But 创建没问题。
让我尝试重新表述这个问题:
- 你有一个模型
Video
Video
有虚拟属性my_link
Video
有一个before_update
回调before_add_to_galerie
- 您希望仅在
my_link
发生更改时触发此回调
这看起来正确吗?
如果是这样,您有 2 个选项,首先 - 如果您有 updated_at
将其与 my_link
class Video < ApplicationRecord
attr_reader :my_link
# ...
def my_link=(val)
return val if val == my_link
@my_link = val
self.updated_at = Time.zone.now
end
end
或者您可以使用 ActiveModel