Rails - 在表单中访问belongs_to关联的foreign_key

时间:2017-04-06 06:04:46

标签: ruby-on-rails ruby associations simple-form

架构:
我有两个型号:端口和应用程序

  • 应用程序属于端口
  • 在App中,关系定义如下:
    belongs_to :port, class_name: 'Port', foreign_key: :port_id, required: true
  • 一个端口有一个数字,显然是一个id(no,id和number不相等)

我需要什么:
端口已存在于数据库中。在应用程序的创建表单中,我列出了所有可用端口:<%= f.association :port, collection: Port.available_ports, include_blank: false %>。 使用此方法,select项的值等于端口的数量。但我需要的是,该值不是数字而是端口的ID。

我尝试了什么: 我尝试通过在f.association中添加以下内容来解决我的问题:value_method: Port.available_ports。但这不起作用:no implicit conversion of Array into String

我的问题:
我是在正确的轨道上还是应该以不同的方式处理我的问题?如果是这样,你会建议我做什么?

修改
    AppController的

class JBossAppsController < ApplicationController

  before_action :load_app,
                only: %i[ show destroy ]

  def index
    @apps = JBossApp.all
  end

  def show
  end

  def new
    @app = JBossApp.new
  end

  def create
    @app = JBossApp.new(app_params)
    if @app.save!
      redirect_to root_path
    else
      render 'j_boss_apps/new'
    end
  end

  def destroy
  end

  protected
  def load_app
    @app = JBossApp.find_by(params[:id])
  end

  private
  def app_params
    params.require(:j_boss_app).permit(
        params.require(:j_boss_app).permit(
            :id, :group_id, :port_id, :environment, :status, :fault_count, :request_count, :response_count
        )
    )
  end

end

端口

class Port < ApplicationRecord


# Helper
  def self.available_ports
    unavailable_ports = Port.order(number: :asc).pluck(:number)
    first_port = 8080
    last_port = 65080
    step = 100
    all_ports = (first_port..last_port).step(step).collect { |n| n }
    all_ports - unavailable_ports
  end

# Relations
  has_many :apps,
           class_name: 'JBossApp',
           foreign_key: :port_id,
           dependent: :destroy

  has_one :int_app, ->{
    where(port_id: id, environment: :int)
  }

  has_one :tst_app, ->{
    where(port_id: id, environment: :tst)
  }

  has_one :prd_app, ->{
    where(port_id: id, environment: :prd)
  }

  has_one :dmz_tst_app, ->{
    where(port_id: id, environment: :dmz_tst)
  }

  has_one :dmz_prd_app, ->{
    where(port_id: id, environment: :dmz_prd)
  }

# Validations
  validates :number,
            numericality: {
                greater_than: 0,
                only_integer: true
            },
            presence: true

end

2 个答案:

答案 0 :(得分:2)

根据我对该问题的理解,您 EITHER 需要将用户输入的端口号插入//Create a file to write bitmap data File file = new File(context.getCacheDir(), yourFilename); file.createNewFile(); //Convert bitmap to byte array Bitmap bitmap = Your bitmap; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 0, bos); byte[] bitmapdata = bos.toByteArray(); //Write the bytes in file FileOutputStream fos = new FileOutputStream(f); fos.write(bitmapdata); fos.flush(); fos.close(); 表并将其与应用相关联,同时保存它或者事先将所有端口播种到String DBerrorCode=DatabaseReturnErrorCode;//Errorcode from Database if("RUREF00001".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00001); }else if("RUREF00002".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00002); } else if("RUREF00003".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00003); } else if("RUREF00004".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00004); } else if("RUREF00005".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00005); } else if("RUREF00006".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00006); } else if("RUREF00027".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00027); } else if("RUREF00028".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00028); } else if("RUREF00029".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00029); } else if("RUREF00030".equals(DBerrorCode)){ throw new DataUpdateException(ErrorRUREF00030); } else { //default error throw new DataUpdateException(DATA_INSERT_ERROR); } 表,然后找到没有相应/关联应用的端口。为此,您可以按如下方式更改Ports方法:

Ports

现在您可以使用普通表单帮助程序方法available_ports作为:

def self.available_ports
  Port.includes(:apps).where(apps: {id: nil}).order(ports:{number: :asc})

  # Or similar results can be achieved by the following in Rails 5
  # Port.left_outer_joins(:apps).where(apps: {id: nil}).order(ports:{number: :asc})
end

如果您需要有关任何建议解决方案的进一步帮助,请与我们联系。

答案 1 :(得分:1)

def self.available_ports
    unavailable_ports = Port.order(number: :asc).pluck(:number)
    first_port = 8080
    last_port = 65080
    step = 100
    all_ports = (first_port..last_port).step(step).collect { |n| n }
    all_ports = all_ports - unavailable_ports
    all_ports = Port.where(number: all_ports)
 end
视图中的

<%= f.collection_select :port_id, Port.available_ports, :id, :number, {prompt: "Select a port"}, {class: "form-control"} %>