Tôi gặp sự cố khi cố gắng cập nhật mô hình có liên kết has_and_belongs_to_many
.Chỉnh sửa đối tượng với cơ sở dữ liệu sửa đổi liên kết HABTM trước khi xác nhận với ActiveAdmin
Giả sử Post
has_and_belongs_to_many
Tag
và Post
xác thực sự hiện diện của tiêu đề và Tags
. Nếu tôi cập nhật Post
, xóa tiêu đề và thẻ, tôi nhận được lỗi xác thực trong title
và tags
, ok. Nhưng ActiveAdmin
đã xóa các bản ghi liên kết giữa Post
và Tag
, vì vậy, nếu tôi rời khỏi trang chỉnh sửa Post
, thì post
sẽ không hợp lệ trên cơ sở dữ liệu, mà không có tags
.
Dưới đây mô hình của tôi:
class Tag < ActiveRecord::Base
attr_accessible :label
has_and_belongs_to_many :posts
end
class Post < ActiveRecord::Base
attr_accessible :content, :title, :tag_ids
has_and_belongs_to_many :tags
validates_presence_of :content, :title, :tags
end
ActiveAdmin.register Post do
form do |f|
f.inputs do
f.input :title
f.input :content
f.input :image
f.input :tags
end
f.buttons
end
end
tôi usign chosen-rails đá quý và nó cho phép người sử dụng để bỏ chọn tất cả các thẻ của bưu điện.
Tóm tắt, vấn đề của tôi là: ActiveAdmin cập nhật các mối quan hệ trên cơ sở dữ liệu trước khi thực hiện xác thực mô hình.
Có một giải pháp cho hành vi này hoặc tôi làm điều gì đó sai?
Edit:
Đây nhật ký yêu cầu khi tôi cố gắng cập nhật bài viết mà không tiêu đề và các thẻ:
Started PUT "/admin/posts/8" for 127.0.0.1 at 2013-04-01 10:32:07 -0300
Processing by Admin::PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"amSbLlP/rgDrNn/N8lgq/KEaRXK1fMPShZDwpZ0QIJ4=", "post"=>{"title"=>"", "content"=>"content", "tag_ids"=>["", ""]}, "commit"=>"Update Post", "id"=>"8"}
AdminUser Load (0.2ms) SELECT `admin_users`.* FROM `admin_users` WHERE `admin_users`.`id` = 1 LIMIT 1
Post Load (0.2ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 8 LIMIT 1
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` INNER JOIN `posts_tags` ON `tags`.`id` = `posts_tags`.`tag_id` WHERE `posts_tags`.`post_id` = 8
(0.1ms) BEGIN
SQL (12.3ms) DELETE FROM `posts_tags` WHERE `posts_tags`.`post_id` = 8 AND `posts_tags`.`tag_id` IN (1, 2)
(49.6ms) COMMIT
(0.1ms) BEGIN
(0.2ms) ROLLBACK
Post Load (0.3ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 8 LIMIT 1
Tag Load (0.2ms) SELECT `tags`.* FROM `tags`
Rendered /home/rodrigo/.rvm/gems/[email protected]/gems/activeadmin-0.5.1/app/views/active_admin/resource/edit.html.arb (192.3ms)
Completed 200 OK in 276ms (Views: 194.8ms | ActiveRecord: 63.3ms)
EDIT 2:
Ok, tôi chắc chắn rằng ActiveAdmin có lỗi này.
Nhìn vào hành vi ActiveRecord, tôi cho rằng luồng xác thực bị hỏng chỉ sử dụng lớp mô hình. Xem ví dụ này:
1.9.3p125 :064 > post = Post.find(8)
Post Load (0.3ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 8 LIMIT 1
=> #<Post id: 8, title: "title", content: "content", created_at: "2013-03-27 13:13:20", updated_at: "2013-03-27 13:13:20", image: "extrato.bmp">
1.9.3p125 :065 > post.tags
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` INNER JOIN `posts_tags` ON `tags`.`id` = `posts_tags`.`tag_id` WHERE `posts_tags`.`post_id` = 8
=> [#<Tag id: 1, label: "tag", created_at: "2013-02-25 18:32:45", updated_at: "2013-02-25 18:32:45">, #<Tag id: 2, label: "new", created_at: "2013-02-25 18:32:50", updated_at: "2013-02-25 18:32:50">]
1.9.3p125 :066 > post.title = ""
=> ""
1.9.3p125 :067 > post.save #<<<<<<< It's invalid on title
=> false
1.9.3p125 :068 > post.tags = [] #<<<<<<< This shouldnt trigger database update
(0.3ms) BEGIN
SQL (0.5ms) DELETE FROM `posts_tags` WHERE `posts_tags`.`post_id` = 8 AND `posts_tags`.`tag_id` IN (1, 2)
(55.5ms) COMMIT
=> []
1.9.3p125 :069 > post.save #<<<<<<< It's invalid on title AND TAGS
(0.2ms) BEGIN
(0.2ms) ROLLBACK
=> false
1.9.3p125 :070 > post.reload
Post Load (0.2ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 8 LIMIT 1
=> #<Post id: 8, title: "title", content: "content", created_at: "2013-03-27 13:13:20", updated_at: "2013-03-27 13:13:20", image: "extrato.bmp">
1.9.3p125 :071 > post.valid? #<<<<<<< Now, I have this model in invalid state
Tag Load (0.6ms) SELECT `tags`.* FROM `tags` INNER JOIN `posts_tags` ON `tags`.`id` = `posts_tags`.`tag_id` WHERE `posts_tags`.`post_id` = 8
=> false
Có cách nào để cập nhật thuộc tính bài (bao gồm thẻ) và xác thực mô hình trước khi thực hiện bất kỳ cập nhật cơ sở dữ liệu nào không?
Bạn không nên có tag_ids trong bài viết của bạn mô hình. Bạn có bảng trung gian trong cơ sở dữ liệu của bạn sẽ phù hợp với mối quan hệ habtm? – Zippie
@Zippie, tôi không có 'tag_ids' trong mô hình của mình. ActiveAdmin chỉ định id của các thẻ trong bài đăng bằng phương thức này do Rails tạo. – Rodrigo
âm thanh lạ, hãy sao chép đính kèm nhật ký truy vấn sql theo yêu cầu của bạn – Fivell