I may be missing something fundamental here, but I can't seem to get ActiveAdmin to work with a sortable has_many through relationship, with the ability to create new records.
So given the following models
class User < ActiveRecord::Base
has_many :user_videos
has_many :videos, through: :user_videos
accepts_nested_attributes_for :user_videos
accepts_nested_attributes_for :videos
...
end
class UserVideo < ActiveRecord::Base
belongs_to :user
belongs_to :video
accepts_nested_attributes_for :video
end
class Video < ActiveRecord::Base
has_many :user_videos
has_many :users, through: :user_videos
...
end
(I admit I'm throwing accepts_nested_attributes_for
around somewhat in the hopes that something may work)
And Active Admin setup goes something like this (WIP of course):
f.inputs "User" do
f.has_many :user_videos, heading: 'Videos', sortable: :order, allow_destroy: true, new_record: 'New Record' do |v|
v.inputs for: :video do |video|
video.input :video_url
end
end
f.has_many :videos, heading: 'Videos', new_record: 'New Video' do |v|
v.input :video_url
end
end
f.actions
The first has_many
on the :user_videos
association does not seem to render any inputs. If there are records there, I can see that video.input :video_url
is actually returning an li
tag with label
and input
, however nothing gets rendered to the page. For new records the whole v.inputs
bit does not get run (do I need to create the child records somehow there first?).
The second has_many
will work in that you'll be able to add records, and update existing records, however it's impossible to sort as the order
column is on the UserVideos
model. I include this more as illustration than anything.
If anyone has any pointers for this, they would be most appreciated. :)
Since nobody seemed interested in tackling this, I took another approach - rather than trying to get ActiveAdmin / Formtastic to work with the existing model structure, I added getters and setters for the necessary field on the intersection model.
class UserVideo < ActiveRecord::Base
belongs_to :user
belongs_to :video
validates_with VideoValidator
def video_url
self.video = Video.create if video.nil?
self.video.video_url
end
def video_url=(video_url)
self.video = Video.create if video.nil?
self.video.video_url = video_url
# Video url is set via Active Admin, AA will not call save on the video as it does not realise it's changed
self.video.save! if video.present? and video.valid?
end
end
Doing this meant that Active Admin did not need to know about the Video model, and could just operate on the UserVideo model:
f.has_many :user_videos, heading: 'Videos', sortable: :order, allow_destroy: true, new_record: 'New Record' do |v|
v.input :video_url, :hint => (v.object.video.embed_code unless v.object.nil? or v.object.video.nil?)
end
If anyone has an actual solution rather than a work around, I'd love to hear it, but otherwise this is a possible solution for anyone searching for an answer to the same problem.