ActiveAdmin从表单文本字段中获取值

时间:2015-12-01 17:43:13

标签: ruby-on-rails ruby forms activeadmin

我是Ruby的新用户,并使用ActiveAdmin进行一些简单的管理。 我有一个模型Question我想创建,填充并存储到数据库,它有一个属性themesTheme模型数组)。当用户创建新记录时,他不会手动输入主题但提供一些字符串,系统将自动解析它并查找或创建主题。所以我有这样的代码:

form do |f|
    f.inputs "Questions Details" do
      f.input :question, as: :string
      f.input :autocomplete_themes, hint: "You should enter here multiple themes,
      divide them with `,` or `;`"
    end
    f.actions
end

它会为输入字符串创建一个新字段autocomplete_themes,并且它不存在于模型Question中。所以我想要的是 - 获取autocomplete_themes值,如字符串,然后使用split()和我的自定义逻辑 - 但它会出错。

before_create do |question|
    array = []
    puts "******"
    puts :autocomplete_themes.text
    themeTitles = :autocomplete_themes.split(",") #split(/,|;/)
    for title in themeTitles do
      theme = Theme.find_by(title: title)
      theme = Theme.create(title: title) unless theme
      array << theme
    end
    question.themes = array
end

问题:如何将autocomplete_themes值作为字符串? THX!

更新:正如我所理解的here - 它看起来像是类似的情况,但是将默认值设置为自定义字段存在问题,但我需要从代码中获取其值。

1 个答案:

答案 0 :(得分:2)

您没有指定所获得的错误,但根据您提供的信息,您不需要Question成为before_create模型的真正数据库支持的属性,而是您只需要临时获取信息,以便autocomplete_themes过滤器可以使用它来执行适当的逻辑。

因此,您可以使Question成为“虚拟属性”,就像class Question < ActiveRecord::Base attr_writter :autocomplete_themes attr_reader :autocomplete_themes ...other code end 实例的传统成员变量。

@question.autocomplete_themes = "1,2,3"
themes_text = @question.auto_complete_themes

这将允许您执行以下操作:

form do |f|
f.inputs "Questions Details" do
  f.input :question, as: :string
  f.input :autocomplete_themes, hint: "You should enter here multiple themes,
  divide them with `,` or `;`"
end
f.actions
end

最重要的是,ActiveAdmin支持将表单输入分配给虚拟属性。所以你可以保持这样的形式:

before_filter

你的before_create do |question| array = [] themeTitles = question.autocomplete_themes.split(",") #split(/,|;/) for title in themeTitles do theme = Theme.find_by(title: title) theme = Theme.create(title: title) unless theme array << theme end question.themes = array end 看起来像这样:

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;

namespace blockbattle
{
    public class AsyncServer
    {
        private const int port = 11000;
        public int clientID = -1;
        public string serverPos = "";
        public string clientPos = "";
        public string newBullets = "";
        public bool bulletsSent = false;
        public string receivedBullets = "";

        public void StartServer()
        {
            Thread thread = new Thread(Run) { IsBackground = true };
            thread.Start();
        }

        private void Run()
        {
            Debug.WriteLine("Running");
            TcpListener tcpListener = new TcpListener(IPAddress.Loopback, port);
            tcpListener.Start();
            while (true)
            {
                Debug.WriteLine("Before Accept");
                ServerState state = new ServerState { WorkSocket = tcpListener.AcceptSocket() };
                Debug.WriteLine("Before Receive");
                Receive(state);
            }
        }

        private void Receive(ServerState state)
        {
            state.WorkSocket.BeginReceive(state.Buffer, 0, ServerState.BufferSize, 0, ReceiveCallBack, state);
        }

        private void ReceiveCallBack(IAsyncResult ar)
        {
            ServerState state = (ServerState)ar.AsyncState;
            try
            {
                int byteReceived = state.WorkSocket.EndReceive(ar);
                if (byteReceived > 0)
                {
                    string receivedString = Encoding.UTF8.GetString(state.Buffer, 0, byteReceived);

                    string[] receivedData = receivedString.Split('+');

                    clientID = int.Parse(receivedData[0]);
                    clientPos = receivedData[1];
                    if (receivedData[2].Length > 0)
                        receivedBullets = receivedData[2];

                    byte[] bytesToSend = Encoding.UTF8.GetBytes(string.Format("{0}+{1}", serverPos, newBullets));
                    if (newBullets.Length > 0)
                    {
                        newBullets = "";
                        bulletsSent = true;
                    }

                    Array.Copy(bytesToSend, state.Buffer, bytesToSend.Length);
                    state.WorkSocket.Send(state.Buffer, 0, bytesToSend.Length, SocketFlags.None);
                    Array.Clear(state.Buffer, 0, state.Buffer.Length);
                    Receive(state);
                }
            }
            catch (Exception e)
            {
                Debug.Print(e.ToString());
            }
        }

        private class ServerState
        {
            public const int BufferSize = 1024;
            public readonly byte[] Buffer = new byte[BufferSize];
            public Socket WorkSocket = null;
        }
    }
}