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

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

ただいまの
回答率

90.35%

  • Ruby on Rails 4

    2464questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Railsのアソシエーションでの値の取り出し方

解決済

回答 2

投稿 編集

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

koichi8888

score 11

 前提・実現したいこと

railsで参照先のカラムの値を取得し、viewに表示したいです。
具体的にはcategory_idから対応するcategoryモデルのnameカラムの値を取得し、viewに表示したいです。
おそらく、index.html.erbのcategory_idの記載をcategoryモデルから取得するように修正する必要があるのですが、
色々試してみたのですが、記載方法が分からないため、教えて頂けますでしょうか。

試行錯誤する中で↓のエラーメッセージが表示されている、また、category_idに1または2しか登録できないことから、アソシエーションの設定には成功していると思います。

試した記載:
<%= @items.each do |item| %>
<%= item.manage_id %>

<% item.category.each do |p| %>
<%= p.name %>
<% end %>

<% end %>

エラーメッセージ:
undefined method `each' for #<Category id: 1, name: "SSL">

モデル名:GyomuDatum

ID category_id※外部キー .. ..
1 1
2 2

モデル名:Category

ID※主キー name
1 A
2 B

モデル名:HistoriesDatum

Operation_id namage_id user_id user_name created_at
1 10001 7 tanaka yyyy/mm/dd/hh:mm
2 10002 8 sato yyyy/mm/dd/hh:mm

 該当のソースコード

gyomu_datum.rb

class GyomuDatum < ActiveRecord::Base

belongs_to :Category

end

category.rb

class Category < ActiveRecord::Base

has_many :GyomuData

end

views/items/index.html.erb

<p class="rei1">データ一覧</p>
<br>

<!-- 権限によってデータ一覧の項目値を変更 -->

<section>

  <table class="type06">
    <thead>

      <% if session[:authority] == "1" %>

     <tr>
      <th>管理ID</th>
      <th>カテゴリ</th>
      <th>発行会社</th>
      <th>IPアドレス</th>
      <th>対象サーバ</th>
      <th>有効期限の開始日</th>
      <th>有効期限の終了日</th>
      <th>コメント</th>
      <th>操作</th>
     </tr>

  </thead>
  <tbody>

    <% @items.each do |item| %>
     <tr>
      <td><%= item.manage_id %></td>
      <td><%= item.category_id %></td>
      <td><%= item.publish_corporation %></td>
      <td><%= item.ip_address %></td>
      <td><%= item.target_server %></td>
      <td><%= item.start_date %></td>
      <td><%= item.end_date %></td>
      <td><%= item.comment %></td>
      <td>
      <%= link_to '[Edit]', edit_item_path(item), class: 'command' %>
      <%= link_to '[Delete]', 
      item_path(item), 
      method: :delete,
      class: 'command',
      data: { confirm: 'データ削除しますか?' } %>
      </td>
     </tr>

    <% end %>


    <% elsif session[:authority] == "2" %>

     <tr>
      <th>管理ID</th>
      <th>カテゴリ</th>
      <th>発行会社</th>
      <th>IPアドレス</th>
      <th>対象サーバ</th>
      <th>有効期限の開始日</th>
      <th>有効期限の終了日</th>
      <th>コメント</th>
     </tr>

      <% @items.each do |item| %>
     <tr>
      <td><%= item.manage_id %></td>
      <td><%= item.category_id %></td>
      <td><%= item.publish_corporation %></td>
      <td><%= item.ip_address %></td>
      <td><%= item.target_server %></td>
      <td><%= item.start_date %></td>
      <td><%= item.end_date %></td>
      <td><%= item.comment %></td>
     </tr>

    <% end %>

    <% else %>

      <!-- データ一覧を表示しない -->

    <% end %>

    </tbody>
  </table>

</section>

item_controller.rb

class ItemsController < ApplicationController

     before_action :authenticate_user


  def index

    # データを降順で表示する
    # @items = GyomuDatum.all.order(created_at: 'desc')

    @items = GyomuDatum.all.includes(:category)

    # データ検索

pp "############データ検索開始############"

      if params[:manage_id].present?
        items = GyomuDatum.where('manage_id LIKE ?', "%#{params[:manage_id]}%")
        pp "manage_id_debug"
        pp items
      elsif params[:category_id].present?
        items = GyomuDatum.where('category_id LIKE ?', "%#{params[:category_id]}%")
        pp "category_id_debug"
        pp items
      elsif params[:publish_corporation].present?
        items = GyomuDatum.where('publish_corporation LIKE ?', "%#{params[:publish_corporation]}%")
        pp "publish_corporation_debug"
        pp items
      pp items
      elsif params[:ip_address].present?
        items = GyomuDatum.where('ip_address LIKE ?', "%#{params[:ip_address]}%")
        pp "ip_address_debug"
        pp items
      elsif params[:target_server].present?
        items = GyomuDatum.where('target_server LIKE ?', "%#{params[:target_server]}%")
      pp "target_server_debug"
      pp items
      elsif params[:start_date].present?
        items = GyomuDatum.where('start_date LIKE ?', "%#{params[:start_date]}%")
      pp "start_date_debug"
      pp items
      elsif params[:end_date].present?
        items = GyomuDatum.where('end_date LIKE ?', "%#{params[:end_date]}%")
      pp "end_date_debug"
      pp items
      elsif params[:comment].present?
        items = GyomuDatum.where('comment LIKE ?', "%#{params[:comment]}%")
      pp "comment_debug"
      pp items
      else
        items = GyomuDatum.all.order(created_at: 'desc')
      pp "all_debug"
      pp items
      end

      pp "elseout"
      pp items

pp "############データ検索終了############"



    # ページネーション
    @items = items.page(params[:page]).per(20)

    # 期限が迫っているデータを検索する

    # 1ヶ月前
    from  = Time.now.at_beginning_of_day
    to    = (from + 1.month)
    @items_1month = GyomuDatum.where(end_date: from...to)

  end

  def show
  end

  def new
    @item = GyomuDatum.new
  end

  def create

    # 変数定義
    manage_id = params[:manage_id]

    @item = GyomuDatum.find(params[:id])
    manage_id = @item.manage_id
    category_id = @item.category_id

    # 現在の時刻取得
    require "date"
    time = DateTime.now

    # 操作履歴登録
    histories = HistoriesDatum.new({manage_id: manage_id, category_id: category_id, type_id: '1', user_id: session[:user_id], user_name: session[:user_name], created_at: time, updated_at: time, deleted_at: ""})
    histories.save


    # render plain: params[:GyomuDatum].inspect
    # save
    # @item = Item.new(params[:GyomuDatum])
    # @item = GyomuDatum.new(params.require(:GyomuDatum).permit(:manage_id, :category_id, :publish_corporation, :ip_address, :target_server, :start_date, :end_date, :comment))
     @item = GyomuDatum.new(item_params)
    # @item.save
    # redirect
    # redirect_to items_path


    # データ登録判定

    if @item.save
      @notice_message = "データ登録成功"
      flash[:notice] = @notice_message
      redirect_to items_path
    else
      @notice_message = "データ登録失敗"
      flash[:notice] = @notice_message
      # render plain: @item.errors.inspect
      render 'new'
    end
  end


  def edit
    @item = GyomuDatum.find(params[:id])
  end

  def update

  # データ更新処理

    # 変数定義
    @item = GyomuDatum.find(params[:id])
    manage_id = @item.manage_id
    category_id = @item.category_id

    # 現在の時刻取得
    require "date"
    time = DateTime.now

    # 操作履歴登録
    histories = HistoriesDatum.new({manage_id: manage_id, category_id: category_id, type_id: '2', user_id: session[:user_id], user_name: session[:user_name], created_at: time, updated_at: time, deleted_at: ""})
    histories.save


   # データ編集処理判定

    if @item.update(item_params)
      @notice_message = "データ編集成功"
      flash[:notice] = @notice_message
      redirect_to items_path
     else
      @notice_message = "データ編集失敗"
      flash[:notice] = @notice_message
      render 'edit'
    end
  end

  def destroy

  # データ削除処理

    # 変数定義
    @item = GyomuDatum.find(params[:id])
    manage_id = @item.manage_id
    category_id = @item.category_id

    # 現在の時刻取得
    require "date"
    time = DateTime.now

    # 操作履歴登録
    histories = HistoriesDatum.new({manage_id: manage_id, category_id: category_id, type_id: '3', user_id: session[:user_id], user_name: session[:user_name], created_at: time, updated_at: time, deleted_at: ""})
    histories.save

    # 削除処理
    @item = GyomuDatum.find(params[:id])
    @item.destroy
    redirect_to items_path
  end



  # cron用メール送信メソッド
  def mail_notice

    # メール送信実行
    SampleMailer.send_when_limit.deliver

  end


    # プライベートメソッド

#  private
#    def item_params
#      params.require(:GyomuDatum).permit(:manage_id)
#      params.require(:gyomu_datum).permit(:manage_id, :category_id, :publish_corporation, :ip_address, :target_server, :start_date, :end_date, :comment)
#      params.require.fetch(:GyomuDatum,{}).permit(:manage_id, :category_id, :publish_corporation, :ip_address, :target_server, :start_date, :end_date, :comment)
#    end

    # プライベートメソッド
    private
    def item_params
      permits = [
        :manage_id,
        :category_id,
        :publish_corporation,
        :ip_address,
        :target_server,
        :start_date,
        :end_date, 
        :comment
      ]
      params.require(:gyomu_datum).permit(permits)
    end

# class範囲終了
end

edit.html.erb

<!-- ↓↓データ編集失敗表示↓↓ -->

    <% if flash[:notice] %>
      <div class="alert alert-success">
      <%= flash[:notice] %>
      </div>
    <% end %>

<!-- ↑↑データ編集失敗表示↑↑ -->

<br>
<br>
<br>
<h2>
<%= form_for @item, url: item_path(@item) do |f| %>
<p class="rei1">データ編集</p>
<p>
  管理ID:
    <br>
  <%= f.text_field :manage_id, placeholder: '管理ID' %>
</p>
<p>
  カテゴリ:
  <br>
<% if false %>
  <%= f.select :category_id, [["SSL", "1"], ["ドメイン", "2"] ] %>
<% end %>

  <%= f.text_field :category_id, placeholder: 'カテゴリ' %>

</p>
<p>
  発行会社:
  <br>
  <%= f.text_field :publish_corporation, placeholder: '発行会社' %>
</p>
<p>
  IPアドレス:
  <br>
  <%= f.text_field :ip_address, placeholder: 'IPアドレス' %>
</p>
<p>
  サーバ名:
  <br>
  <%= f.text_field :target_server, placeholder: 'サーバ名' %>
</p>
<p>
  有効期限の開始:
  <br>
  <%= f.text_field :start_date, placeholder: '2018-04-01' %>
</p>
<p>
  有効期限の終了:
  <br>
  <%= f.text_field :end_date, placeholder: '2018-04-01' %>
</p>
<p>
  コメント:
  <br>
  <%= f.text_area :comment, placeholder: 'コメント' %>
</p>
<p>
<br>
  <%= f.submit "編集完了" , class: "btn btn-primary"%>
</p>


<% end %>

 補足情報(FW/ツールのバージョンなど)

・Apache
Server version: Apache/2.4.6 (CentOS)

・Rails
Rails 4.2.10

・OSバージョン
$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

・Mysql
mysql  Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using  EditLine wrapper

・Ruby
ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-linux]

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

controllerの実装も教えてもらえますか?

見てる感じだと、以下のような感じですか?

@items = GyomuDatum.all
or
@items = GyomuDatum.where(・・・

もしそうだとすれば
GyomuDatumから見たCategoryは一つしか結びつかないので
(DB上も一つのGyomuDatumに対して、category_idは一つしか格納できませんよね?)

item.category.name
で取得できると思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/11 11:58

    ご回答有難うございます。教えて頂いた通り、item.category.nameでcategoryモデルからデータを取得することができました。
    はまっていたので、大変助かりました。
    テーブル間の連携はできたのですが、データ登録/編集/削除処理の各メソッドで操作履歴をテーブルに記録する処理があるのですが、↓のエラーが表示されるようになりました。
    ##ここから##
    ActiveRecord::InvalidForeignKey in ItemsController#update
    Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails
    (`Myapp_development`.`histories_data`, CONSTRAINT `fk_rails_738067d333` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)): INSERT INTO `histories_data` (`manage_id`, `category_id`, `type_id`, `user_id`, `user_name`, `created_at`, `updated_at`) VALUES ('1', 0, 2, 7, 'oshima001', '2018-06-11 11:22:18', '2018-06-11 11:22:18')
    ##ここまで##

    外部キーのカラムのデータを登録する際はcategoryモデルのIDに存在する整数を登録する(※あくまで表示のみcategoryモデルのnameカラムから取得したデータを表示している認識のため)と思っているのですが、category_idに明示的に1または2を登録する処理をコントローラに記載してもエラーになります。edit.html.erbとitems_controller.rb、操作履歴のテーブル情報を追記するので、何かご存知であれば、教えて頂ければ、幸いです。

    キャンセル

0

エラー見る限り、★をつけたとこでエラーになってるのかなと思います。

def create
  # 変数定義
  manage_id = params[:manage_id]

  @item = GyomuDatum.find(params[:id])
  manage_id = @item.manage_id
  category_id = @item.category_id

  # 現在の時刻取得
  require "date"
  time = DateTime.now

  # 操作履歴登録
  histories = HistoriesDatum.new({manage_id: manage_id, category_id: category_id, type_id: '1', user_id: session[:user_id], user_name: session[:user_name], created_at: time, updated_at: time, deleted_at: ""})
  histories.save ★

category_idに明示的に1または2を登録する処理をコントローラに記載してもエラーになります。

これは、★をつけた行の上の行を、以下のように変えたということ?

category_id: category_id
↓
category_id: 1

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • Ruby on Rails 4

    2464questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。