rails form_with 中关联模型的路径问题
Posted
技术标签:
【中文标题】rails form_with 中关联模型的路径问题【英文标题】:Pathing issues in rails form_with for associated model 【发布时间】:2018-02-24 11:17:36 【问题描述】:我正在处理一个项目,我必须分析文件中的数据,用户应该能够上传该文件。我有一个模型 InputFile,并选择为我的 Analysis 模型实现一个 analysis_facade,它捆绑了大部分功能。 这是模型
#app/models/analysis.rb
class Analysis < ApplicationRecord
has_one :input_file, dependent: :destroy
end
#app/models/input_file.rb
class InputFile < ApplicationRecord
belongs_to :analysis
has_many :access_data, dependent: :destroy
def uploaded_file=(file_field)
self.name = File.basename(file_field.original_filename).gsub(/[^\w._-]/,'')
self.content_type = file_field.content_type.chomp
self.data = file_field.read
end
end
我的 AnalysisController 和相应的外观模式来了
#app/controllers/analyses_controller.rb
class AnalysesController < ApplicationController
before_action :set_analysis, only: :show
def show
@analysis_facade = AnalysisFacade.new(@analysis)
end
private
def set_analysis
@analysis ||= Analysis.create
end
end
#app/facades/analysis_facade.rb
class AnalysisFacade
attr_reader :analysis
def initialize(analysis)
@analysis = analysis
end
def new_input_file
@input_file = analysis.build_input_file
end
def input_file
@input_file ||= new_input_file
end
def access_data
@access_data ||= analysis.input_file.access_data
end
end
我的 InputFiles 控制器
#app/controllers/input_files_controller.rb
class InputFilesController < ApplicationController
include LogFileScanner
before_action :set_analysis, only: [:new, :create, :update]
def new
@input_file = Input_file.new
end
def create
@input_file = @analysis.build_input_file(input_file_params)
if @input_file.save
access_data = scan(@input_file.data)
@input_file.access_data.create(access_data)
end
end
def update
@input_file = @analysis.input_file
if @input_file.update
access_data = scan(@input_file.data)
@input_file.access_data.update(access_data)
end
end
private
def input_file_params
params.require(:input_file).permit(:uploaded_file, :analysis_id)
end
def set_analysis
@analysis = Analysis.find(params[:input_file][:analysis_id])
end
end
对于文件上传,我有这些观点
#app/views/analyses/show.html.erb
<%= render template: 'input_files/get' %>
#app/views/input_files/get.html.erb
<%= form_with model: [@analysis_facade.analysis, @analysis_facade.input_file], action: :update, html: multipart: true, class: 'form-horizontal center' do |form| %>
<div class='form-group.new'>
<% if false %>
<%= form.hidden_field :analysis_id, value: @analysis_facade.analysis[:id] %>
<% end %>
<%= form.file_field 'uploaded_file' %>
<%= form.submit "Upload", class: 'btn btn-default btn-primary' %>
</div>
<% end %>
执行此操作会导致错误
undefined method `analysis_input_files_path' for #<#<Class:0x00007f1208040288>:0x00007f11f0d71d48>
Did you mean? analysis_path
对于这个地方
<%= form_with model: [@analysis_facade.analysis, @analysis_facade.input_file], action: :update, html: multipart: true,
class: 'form-horizontal center' do |form| %>
这是为什么呢?我需要将 analysis_id 传递给 params 以创建新的 InputFile。但我希望它比手动添加 hidden_field 更干净,因为 model_with 应该提供此功能。我在这里想念什么?
另外:为什么 rails 会搜索 `analysis_input_files_path'?它显然是一个has_one关系,那么它不应该寻找analysis_input_file_path吗?
编辑:
#bin/rails routes
Prefix Verb URI Pattern Controller#Action
analyses GET /analyses(.:format) analyses#index
POST /analyses(.:format) analyses#create
new_analysis GET /analyses/new(.:format) analyses#new
edit_analysis GET /analyses/:id/edit(.:format) analyses#edit
analysis GET /analyses/:id(.:format) analyses#show
PATCH /analyses/:id(.:format) analyses#update
PUT /analyses/:id(.:format) analyses#update
DELETE /analyses/:id(.:format) analyses#destroy
input_file_access_data GET /input_files/:input_file_id/access_data(.:format) access_data#index
POST /input_files/:input_file_id/access_data(.:format) access_data#create
new_input_file_access_datum GET /input_files/:input_file_id/access_data/new(.:format) access_data#new
edit_access_datum GET /access_data/:id/edit(.:format) access_data#edit
access_datum GET /access_data/:id(.:format) access_data#show
PATCH /access_data/:id(.:format) access_data#update
PUT /access_data/:id(.:format) access_data#update
DELETE /access_data/:id(.:format) access_data#destroy
input_files GET /input_files(.:format) input_files#index
POST /input_files(.:format) input_files#create
new_input_file GET /input_files/new(.:format) input_files#new
edit_input_file GET /input_files/:id/edit(.:format) input_files#edit
input_file GET /input_files/:id(.:format) input_files#show
PATCH /input_files/:id(.:format) input_files#update
PUT /input_files/:id(.:format) input_files#update
DELETE /input_files/:id(.:format) input_files#destroy
analyses_show GET /
【问题讨论】:
【参考方案1】:我是一个概念错误。我将立面模型更改为
class AnalysisFacade
attr_reader :analysis
def initialize(analysis)
@analysis = analysis
end
def new_input_file
@analysis.build_input_file
end
def input_file
@analysis.input_file ||= new_input_file
end
def access_data
@analysis.input_file.access_data
end
end
视图现在像这样工作
<%= form_with model: @analysis_facade.input_file, html: multipart: true, class: 'form-horizontal center' do |form| %>
<div class='form-group.new'>
<%= form.file_field 'uploaded_file' %>
<%= form.submit "Upload", class: 'btn btn-default btn-primary' %>
</div>
<% end %>
【讨论】:
以上是关于rails form_with 中关联模型的路径问题的主要内容,如果未能解决你的问题,请参考以下文章
Rails form_with(remote:true)错误