ActiveAdmin / Formtastic可以通过关系进行排序

时间:2016-09-16 07:24:06

标签: ruby-on-rails activeadmin formtastic

我可能会遗漏一些基本的东西,但我似乎无法让ActiveAdmin使用可排序的has_many关系,并能够创建新记录。

所以给出以下模型

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

(我承认我在某种程度上投掷了accepts_nested_attributes_for,希望有些事情可以发挥作用)

Active Admin设置就像这样(当然是WIP):

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

has_many关联中的第一个:user_videos似乎没有呈现任何输入。如果有记录,我可以看到video.input :video_url实际上正在返回带有lilabel的{​​{1}}标记,但是没有任何内容呈现给页面。对于新记录,整个input位不会运行(我是否需要先以某种方式创建子记录?)。

第二个v.inputs将起作用,您将能够添加记录并更新现有记录,但由于has_many列位于其上,因此无法对其进行排序order模型。我把它作为插图而不是任何东西。

如果有人对此有任何指示,他们将非常感激。 :)

2 个答案:

答案 0 :(得分:2)

WHOA!我知道我迟到了,但这是利用:delegate method的绝佳机会!

您的UserVideo类看起来像这样

import java.util.ArrayList;
import java.util.Scanner;

public class Route3 {
  public static int minDistance(ArrayList<Long> mindist, ArrayList<Boolean> visited){
    long min = Long.MAX_VALUE;
    int minindex = -1;
    for (int i = 0; i < mindist.size(); i++) {
        if(!visited.get(i) && (mindist.get(i) <= min)) {
            min = mindist.get(i);
            minindex = i;
        }
    }
    return minindex;
}
public static long dijkstra(long[][] graph, int start, int end) {
    int computers = graph.length;
    ArrayList<Boolean> traversed = new ArrayList<>(); //Hold traversed nodes
    for (int i = 0; i < computers; i++) {
        traversed.add(i,false);
    }
    ArrayList<Long> mindist = new ArrayList<>(); //Holds mindistances to nodes based on index
    for (int i = 0; i < computers; i++) {
        mindist.add(i,Long.MAX_VALUE);
    }
    mindist.set(start,(long)0);

    for (int i = 0; i < computers; i++) {
        int min = minDistance(mindist,traversed);
        if(min == -1) return mindist.get(end);
        traversed.set(min,true);
        if(min == end) return mindist.get(min) == Long.MAX_VALUE ? -1 : mindist.get(min); //Error check
        for (int j = 0; j < computers; j++) {
            if(!traversed.get(j) && graph[min][j] != 0 && mindist.get(min) + graph[min][j] < mindist.get(j)) {
                mindist.set(j,(mindist.get(min) + graph[min][j]));
            }

        }

    }
    return mindist.get(end) == Long.MAX_VALUE ? -1 : mindist.get(end);
}
public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    int computers = in.nextInt(); //nodes
    int connections = in.nextInt(); //edges
    int start = in.nextInt();
    int end = in.nextInt();

    long[][] graph = new long[computers+1][computers+1];

    for (int i = 0; i < connections; i++) {
        int x = in.nextInt();
        int y = in.nextInt();
        long t = in.nextLong();
        graph[x][y] = t;
        graph[y][x] = t;
    }
    if(connections == 0) {
        System.out.println(-1);
        System.exit(0);
    }
    long dist = dijkstra(graph,start,end);
    if(dist != -1) System.out.println(dist);
    else System.out.println(-1);
 }
}

祝你好运!

答案 1 :(得分:1)

由于没有人似乎对解决这个问题感兴趣,我采取了另一种方法 - 而不是试图让ActiveAdmin / Formtastic使用现有的模型结构,我在交集模型上添加了必要字段的getter和setter。

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

这样做意味着Active Admin不需要了解视频模型,只能在UserVideo模型上运行:

  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

如果有人有一个实际的解决方案而不是一个解决方案,我很乐意听到它,但对于那些寻找同一问题答案的人来说,这是一个可能的解决方案。