0

この Rails アプリを作成する過程で、私は学んでいることを覚えておいてください。

私のアプリには、Deployment と Service の 2 つのモデルがあります。サービスには多数のデプロイメントがあり、各デプロイメントはサービスに属します。デプロイメント モデルには、属性 :service_name と :service_id があります。ここで、:service_id は外部キーです。

新しいデプロイメントを作成するためのフォームに :service_name のフィールドがありますが、:service_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

これは、ユーザーが :service_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

'

4

2 に答える 2

1

あなたの問題は、検証の失敗時に@deployment変数を設定していないが、ビューで変数にアクセスしようとしていることです(render action: 'new'コントローラーにあるため)。

@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

編集:また、コードに s がいくつか欠けていることに気付きendました。それが見落としであったかどうかはわかりません。それはまったく別のエラーを引き起こすからです。

于 2013-06-05T23:51:36.923 に答える
0

私がこれを正しく読んでいる場合、サービスがまだデータベースにない場合は、別のページにリダイレクトしてサービスを作成しますか?

ルートをどのように設定したかはわかりませんが、使用している場合

resources :services

次のようなことができます

redirect_to new_service_url

render ステートメントの代わりに if の内部。

レールでのリダイレクトの詳細

于 2013-06-05T23:19:54.767 に答える