Ruby on rails RubyonRails表单要求另一个模型具有特定的条目

Ruby on rails RubyonRails表单要求另一个模型具有特定的条目,ruby-on-rails,ruby,forms,validation,null,Ruby On Rails,Ruby,Forms,Validation,Null,请记住,我在构建这个Rails应用程序的过程中正在学习 我的应用程序中有两个型号:部署和服务。服务有许多部署,每个部署都属于一个服务。在部署模型中,我有属性:service\u name和:service\u id,其中:service\u id是外键 我想让创建新部署的表单有一个字段:service\u name,而不是:service\u id,因为这更直观 这就是我试图在部署控制器中实现它的方式 def create @name = params[:deployment][:ser

请记住,我在构建这个Rails应用程序的过程中正在学习

我的应用程序中有两个型号:部署和服务。服务有许多部署,每个部署都属于一个服务。在部署模型中,我有属性:service\u name和:service\u id,其中:service\u id是外键

我想让创建新部署的表单有一个字段:service\u name,而不是:service\u id,因为这更直观

这就是我试图在部署控制器中实现它的方式

def create
    @name = params[:deployment][:service_name]
    @service = Service.find_by_name(@name)

    **if @service.nil?
        render :action => "new" , notice:'Service name (case sensitive) not found!'**
    else 
        @deployment = @service.deployments.new(params[:deployment])

    respond_to do |format|
      if @deployment.save
        format.html { redirect_to @service, notice: 'Deployment was successfully created.' }
        format.json { render json: @service, status: :created, location: @service}
      else
        format.html { redirect_to @service, notice: 'Please enter all necessary fields.' }
        format.json { render json: @deployment.errors, status: :unprocessable_entity }
  end
@name = params[:deployment][:service_name]
@service = Service.find_by_name(@name)

if @service.nil?
    @deployment = Deployment.new(params[:deployment]) # Guessing, but this is probably what you want.
    render(:action => "new" , notice:'Service name (case sensitive) not found!')
    return  # Added this so we don't accidentally try rendering twice
else 
    @deployment = @service.deployments.new(params[:deployment])
end
只要用户提交的内容:service\u name存在于我的服务表中,这一切都很好。否则,我将得到以下错误,因为@service将为null

Rails专家们,处理这个错误的最佳方法是什么?现在我有一个基本的if语句(粗体),但它没有达到我的目的。谢谢

NoMethodError in Deployments#create

Showing C:/ruby_training/ServiceRegistry/app/views/deployments/_form.html.erb where line #1 raised:

undefined method `model_name' for NilClass:Class
Extracted source (around line #1):

1: <%= form_for(@deployment) do |f| %>
2:   <% if @deployment.errors.any? %>
3:     <div id="error_explanation">
4:       <h2><%= pluralize(@deployment.errors.count, "error") %> prohibited this deployment from being saved:</h2>
Trace of template inclusion: app/views/deployments/new.html.erb

Rails.root: C:/ruby_training/ServiceRegistry

Application Trace | Framework Trace | Full Trace
app/views/deployments/_form.html.erb:1:in `_app_views_deployments__form_html_erb___545233454_35802348'
app/views/deployments/new.html.erb:3:in `_app_views_deployments_new_html_erb__57703416_31561704'
app/controllers/deployments_controller.rb:56:in `create
NoMethodError在部署中#创建
显示C:/ruby#u training/ServiceRegistry/app/views/deployments/_form.html.erb,其中第1行出现:
NilClass:Class的未定义方法“model_name”
提取的源(第1行附近):
1: 
2:   
三:
4:禁止保存此部署:
模板包含跟踪:app/views/deployments/new.html.erb
Rails.root:C:/ruby\u training/ServiceRegistry
应用程序跟踪|框架跟踪|完整跟踪
app/views/deployments/_-form.html.erb:1:in`_-app\u-views\u-deployments\u-form\u-html\u-erb\u 545233454\u 35802348'
app/views/deployments/new.html.erb:3:in`_app_views_deployments_new_html_erb_57703416_31561704'
app/controllers/deployments\u controller.rb:56:in`create

如果我读对了,如果数据库中还没有服务,您想将它们重定向到其他页面来创建服务吗

我不确定您是如何设置路线的,但如果您使用

resources :services
你可以这样做

redirect_to new_service_url
在if中,而不是在render语句中


您的问题是,在验证失败时,您没有设置
@deployment
变量,但它正试图在视图中访问它(因为您在控制器中有
呈现操作:“新建”


编辑:我还注意到您的代码中缺少了一些
end
s,不确定这是否是疏忽。一定是因为那会导致完全不同的错误。

我认为这不是他想要的。这更像是验证失败,他希望表单重新填充输入的数据,但显示一条错误消息,以便您可以更正一个字段。我认为他在错误的地方做了验证检查(应该在模型的某个地方而不是控制器中进行检查)。nzifnab是正确的。我不确定如何在模型中进行验证,因为验证取决于:service_名称是否存在于另一个表(Services)中。我喜欢这个答案。不是我特别想要的,但它很有效。谢谢还有一件事——关于在rails中处理HTTP api请求的良好起点(ie教程)有什么建议吗?这属于它自己的问题;)但我可能会查看
HTTParty
gem或
json\u生成器
gem,这取决于您是想访问外部API,还是想分别充当外部API。