导轨 - 的形式belongs_to的关联的接入foreign_key
架构:
我有两个模型:端口和App导轨 - 的形式belongs_to的关联的接入foreign_key
- 的应用程序属于端口
- 在APP的关系等定义以下:
belongs_to :port, class_name: 'Port', foreign_key: :port_id, required: true
- 甲端口具有多个和明显的ID(无,ID和数目不相等)
我需要的是:
端口已经存在于数据库中。在应用程序的创建表单中,我列出了包含所有可用端口的列表:<%= f.association :port, collection: Port.available_ports, include_blank: false %>
。 使用这种方法,选择项的值等于端口号。但我需要的是,价值不是数字,而是港口的身份。
我的尝试: 我试图通过添加以下到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
按我的理解的问题,你会无论是需要插入用户输入端口号为Ports
表,并将其关联到应用程序,同时将其保存OR种子所有端口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
现在你可以使用你的正常形式的辅助方法collection_select
为:
<%= f.collection_select :port_id, Port.available_ports, :id, :number, {prompt: "Select a port"}, {class: "form-control"} %>
请让我知道如果你需要更多的帮助与任何提出解决方案
“需要将用户输入的端口号插入到端口表中,并将其保存到应用程序中”是正确的。 –
等一下..我刚刚与我的同事进行了一次讨论。他让我试试你的解决方案。有了这个,我得到一个空的列表。我将函数改为:'Port.includes(:apps).where(j_boss_apps:{port_id:nil})'来简化它。但正如我所说:名单仍然是空的。你认为什么可能是错的? –
您是否已将所有端口添加到表中?确保表格中的所有端口位于8080和65080之间。 –
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"} %>
没有错误,但列表是空的... –
@colin Herzog您需要将可用的端口号插入端口表中,然后您将获得列表。 –
好点。但是,如果端口号已经在表中,是不是不可用的端口? 'unavailable_ports = Port.order(number :: asc).pluck(:number)':) –
参见API文档 http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select –
@Dnyanarthlonkar它是数字,而不是名称。如果我改变它出现错误出现:'8080的未定义方法编号:Fixnum 您的意思是?分子' –
您可以使用您想要在选择列表中显示的属性而不是名称,即替换您想显示的attritube而不是名称 –