質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Ruby

    7054questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    6755questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Railsのファイル読み込み時のエラーについて教えてください。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 216

koume

score 198

Rails5.1.3でWebアプリケーション制作の勉強中です。口座のアカウントの更新ページを作ってみようと動作確認しているのですが、エラーが出てしまい自力で解決出来ずに困っております。やろうとしていることは以下になります。

1,「編集」をクリックするとログイン中のユーザーのレコードを表示する。(Banksテーブルのレコードを表示する。)
・editアクションでbank_form.rbを@bank_formに代入する。 *ここでエラーが出ます。
・部分テンプレート_form.html.erbを読み込みさらに_bank_fields.html.erbでBank_Form_Presenterを読み込み登録済みの内容を表示する。

2,編集画面に変更内容を記述する。
・変更したい内容を記述する。

3,「確認画面へ進む」をクリックし更新画面で編集内容を確認する。
・confirmアクションでbank_form.rbを@bank_formに代入する。 *たぶんここでもエラーが出ます。
・部分テンプレート_confirming_form.html.erbを読み込みさらに_bank_fields.html.erbでConfirming_Bank_Form_Presenter.rbを読み込み編集した内容を表示する。

4,「更新」をクリックし更新する。(Banksテーブルに保存する。)
・updateアクションで保存。

このような流れで更新したくて記述しましたが bank_form.rbのコードが上手く機能してくれません。(エラーが出てしまいます。)
bk_nameというメソッドが定義されていないというエラーがでてしまいますが、解決策がわからなくて困っております。
コードは 以下になります。

banks_controller.rb

 def edit
   @bank_form = Customer::BankForm.new(current_customer)
 end

  # PATCH
  def confirm
    @bank_form = Customer::BankForm.new(current_customer)
    @bank_form.assign_attributes(bank_params)
    if @bank_form.valid?
      render action: 'confirm'
    else
      flash.now.alert = '入力に誤りがあります。'
      render action: 'edit'
    end
  end

  def update
    @bank_form = Customer::BankForm.new(current_customer)
    @bank_form.assign_attributes(bank_params)
    if params[:commit]
      if @bank_form.save
        flash.notice = '口座アカウントを更新しました。'
        redirect_to :customer_root
      else
        flash.now.alert = '入力に誤りがあります。'
        render action: 'edit'
      end
    else
      render action: 'edit'
    end
  end

  private
  def bank_params
    params.permit(bank: [:bk_name, :office, :account, :acc_name, :acc_name_kana])
  end
end
bank_form.rb

class Customer::BankForm
  include ActiveModel::Model

  attr_accessor :bank 
  delegate :persisted?, :valid?, :save, to: :bank

  def initialize(bank = nil)
    @bank = bank
    @bank ||= Bank.new
    @customer.build_bank unless @bank
  end

  def assign_attributes(params = {})
    @params = params
  end

  private
  def bank_params
    @params.permit(bank: [:bk_name, :office, :account, :acc_name, :acc_name_kana])
  end
end
edit.html.erb

<% @title = '口座アカウントの編集' %>
<h1><%= @title %></h1>

<div id="generic-form">
  <%= form_for @bank_form, as: 'form', url: :confirm_customer_bank do |f| %>
    <%= render 'form', f: f %>
    <div class="buttons">
      <%= f.submit '確認画面へ進む' %>
      <%= link_to 'キャンセル', :customer_root %>
    </div>
  <% end %>
</div>
_bank_fields.html.erb

<%= f.fields_for :bank, f.object.bank do |ff| %>
  <%= markup do |m|
    p = confirming ? ConfirmingBankFormPresenter.new(ff, self) :  BankFormPresenter.new(ff, self)
    p.with_options(required: true) do |q|
      m << q.bk_name_block(:bk_name, '銀行名')
      m << q.office_block(:office, '支店名')
      m << q.account_block(:account, '口座番号')
      m << q.acc_name_block(:acc_name, '口座名義')
      m << q.acc_name_kana_block(:acc_name_kana, '口座名義(フリガナ)')
    end
  end %>
<% end %>
Bank_Form_Presenter.rb

class BankFormPresenter < FormPresenter
  def bk_name_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m << error_messages_for(name)
    end
  end

  def office_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m << error_messages_for(name)
    end
  end

  def account_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m.span ' (普通預金口座番号のみ)', class: 'notes'
      m << error_messages_for(name)
    end
  end

  def acc_name_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m.span ' (本人名以外は無効です。)', class: 'notes'
      m << error_messages_for(name)
    end
  end

  def acc_name_kana_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m.span ' (カタカナで入力してください。)', class: 'notes'
      m << error_messages_for(name)
    end
  end
end


「編集」をクリックして時に出るエラーは以下になります。

NoMethodError in Customer::Banks#edit
Showing /home/vagrant/chibi/chibi/app/views/customer/banks/_bank_fields.html.erb where line #8 raised:

undefined method `bk_name' for #<Customer:0x007f5adc339490>
Extracted source (around line #5):         

4  attr_reader :form_builder, :view_context
5  delegate :label, :text_field, :password_field, :check_box, :radio_button, :text_area, :bk_name, :object, to: :form_builder
6
7  def initialize(form_builder, view_context)
8    @form_builder = form_builder


コンソールには以下のように表示されます。

ActionView::Template::Error (undefined method `bk_name' for #<Customer:0x007f5ad 
c339490>):                                                                                                                                                            

     7:     p.with_options(required: true) do |q|
     8:       m << q.bk_name_block(:bk_name, '銀行名')
     9:       m << q.office_block(:office, '支店名')
    10:       m << q.account_block(:account, '口座番号')
    11:       m << q.acc_name_block(:acc_name, '口座名義')


コントローラの@bank_form = Customer::BankForm.new(current_customer)の部分を
@bank_form = current_customer にすると_bank_fields.html.erbを読み込んでくれて3つのアクションは機能して
表示だけはされますが更新してくれません。bank_form.rbに問題があると思うのですが自力ではどうしようもないのでどなたか教えていただけないでしょうか?宜しくお願いします。

bank_form.rbでbk_nameを定義すれば解決できるのかな?とは思いますが、だとしても定義の仕方がわからないのです。
初心者なので長々と内容を全て記述させていただきました。お忙しいとは思いますが教えてください。お願いします。

追記

form_presenter.rb

class FormPresenter
  include HtmlBuilder

  attr_reader :form_builder, :view_context
  delegate :label, :text_field, :password_field, :check_box, :radio_button, :text_area, :bk_name, :object, to: :form_builder

  def initialize(form_builder, view_context)
    @form_builder = form_builder
    @view_context = view_context
  end

   def notes
    markup(:div, class: 'notes') do |m|
      m.span '*', class: 'mark'
      m.text '印の付いた項目は入力必須です。'
    end
  end

  def text_field_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      if options[:maxlength]
        m.span "(#{options[:maxlength]}文字以内)", class: 'instruction'
      end
      m << error_messages_for(name)
    end
  end

  def number_field_block(name, label_text, options = {})
    markup(:div) do |m|
      m << decorated_label(name, label_text, options)
      m << form_builder.number_field(name, options)
      if options[:max]
        max = view_context.number_with_delimiter(options[:max].to_i)
        m.span "(最大値: #{max})", class: 'instruction'
      end
      m << error_messages_for(name)
    end
  end

  def password_field_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << password_field(name, options)
      m << error_messages_for(name)
    end
  end

  def nickname_field_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      #m.span ' (半角英数字で入力してください。)', class: 'notes'
      m << error_messages_for(name)
    end
  end

  def sponsor1_field_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << text_field(name, options)
      m.span ' (紹介者不在の場合はそのまま。)', class: 'notes'
      m << error_messages_for(name)
    end
  end

  def date_field_block(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      if options[:class].kind_of?(String)
        classes = options[:class].strip.split + [ 'datepicker' ]
        options[:class] = classes.uniq.join(' ')
      else
        options[:class] = 'datepicker'
      end
      m << text_field(name, options)
      m << error_messages_for(name)
    end
  end

  def drop_down_list_block(name, label_text, choices, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m << form_builder.select(name, choices, { include_blank: true }, options)
      m << error_messages_for(name)
    end
  end

  def error_messages_for(name)
    markup do |m|
      object.errors.full_messages_for(name).each do |message|
        m.div(class: 'error-message') do |m|
          m.text message
        end
      end
    end
  end

  def decorated_label(name, label_text, options = {})
    label(name, label_text, class: options[:required] ? 'required' : nil)
  end

  def bk_name(name, label_text, options = {})
    markup(:div, class: 'input-block') do |m|
      m << decorated_label(name, label_text, options)
      m.div(object.send(name), class: 'field-value')
      m << hidden_field(name, options)
    end
  end
end
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

situmonnno内容を変えさせていただきます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    7054questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    6755questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。