Rails 4 - HABTM 关联并在关联视图中显示属性

Rails 4 - HABTM associations and displaying attributes in associated view

我正在尝试在 Rails 4.

中制作一个应用程序

我有一个行业模型和一个配置文件模型。

我的行业 table 有:

create_table "industries", force: :cascade do |t|
    t.string   "sector"
    t.string   "icon"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "industries_organisations", id: false, force: :cascade do |t|
    t.integer "industry_id"
    t.integer "organisation_id"
  end

  add_index "industries_organisations", ["industry_id"], name: "index_industries_organisations_on_industry_id", using: :btree
  add_index "industries_organisations", ["organisation_id"], name: "index_industries_organisations_on_organisation_id", using: :btree

  create_table "industries_profiles", id: false, force: :cascade do |t|
    t.integer "industry_id"
    t.integer "profile_id"
  end

  add_index "industries_profiles", ["industry_id"], name: "index_industries_profiles_on_industry_id", using: :btree
  add_index "industries_profiles", ["profile_id"], name: "index_industries_profiles_on_profile_id", using: :tree

协会是:

profile.rb

has_and_belongs_to_many :industries

industry.rb

has_and_belongs_to_many :profiles

在我的个人资料显示中,我试图显示与该个人资料关联的行业(部门属性)。

我不确定如何使用 HABTM 加入 table 协会来做到这一点。

我目前的尝试是:

<% unless @profile.industries.blank? %>
                     <!-- @profile.industry.first.try(:sector) -->
                     <%= @Industry.sector.first = Industry.includes(:profile).where(profile: { @profile })  %>

                <% end %>

注释掉的那一行是我之前的尝试。

我找到了这个我认为我已经关注的资源 Rails - HABTM Relationship -- How Can I Find A Record Based On An Attribute Of The Associated Model

如何显示个人资料的行业领域?

配置文件控制器有:

class ProfilesController < ApplicationController
  before_action :set_profile, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!
  after_action :verify_authorized

  # GET /profiles
  # GET /profiles.json
  def index
    @profiles = Profile.all
    authorize @profiles
  end

  # GET /profiles/1
  # GET /profiles/1.json
  def show
  end

  # GET /profiles/new
  def new
    @profile = Profile.new
    @profile.qualifications_build
    @profile.build_vision
    @profile.build_personality 
    @profile.addresses_build
    @profile.industries_build

    authorize @profile

  end

  # GET /profiles/1/edit
  def edit
    @profile.build_personality unless @profile.personality
    @profile.qualifications_build unless @profile.qualifications
    @profile.build_vision unless @profile.vision
    @profile.addresses_build unless @profile.addresses
    @profile.industries.build unless @profile.industries

  end

  # POST /profiles
  # POST /profiles.json
  def create
    @profile = Profile.new(profile_params)
    authorize @profile

    respond_to do |format|
      if @profile.save
        format.html { redirect_to @profile }
        format.json { render :show, status: :created, location: @profile }
      else
        format.html { render :new }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /profiles/1
  # PATCH/PUT /profiles/1.json
  def update

    # successful = @profile.update(profile_params)

    # Rails.logger.info "xxxxxxxxxxxxx"
    # Rails.logger.info successful.inspect
    # user=@profile.user
    # user.update.avatar
    respond_to do |format|
      if @profile.update(profile_params)
        format.html { redirect_to @profile }
        format.json { render :show, status: :ok, location: @profile }
      else
        format.html { render :edit }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /profiles/1
  # DELETE /profiles/1.json
  def destroy
    @profile.destroy
    respond_to do |format|
      format.html { redirect_to profiles_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_profile
      @profile = Profile.find(params[:id])
      authorize @profile
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def profile_params
     params.require(:profile).permit(:user_id, :title, :hero, :overview, :research_interest, :occupation, :external_profile, 
        :working_languages, :tag_list,
          user_attributes: [:avatar],
          personality_attributes: [:average_day, :fantasy_project, :preferred_style],
          vision_attributes: [:id, :profile_id, :long_term, :immediate_challenge], 
          qualifications_attributes: [:id, :level, :title, :year_earned, :pending, :institution, :_destroy],
          addresses_attributes: [:id, :unit, :building, :street_number, :street, :city, :region, :zip, :country, :latitude, :longitude, :_destroy],
          industries_attributes: [:id, :sector, :icon] )
    end
end

配置文件表单包括行业属性的部分表单:

配置文件表单

          <%= render 'industries/industry_selector', f: f %>  

产业形态

<%= simple_fields_for :industries do |iff| %>

                <div class="form-inputs">

                    <%= iff.label "Choose your industry" %>



<%= iff.select :sector, options_from_collection_for_select(Industry.alphabetically, 'id', 'sector', @profile.industries.map{ |j| j.id }), :multiple => true %>

采纳以下 OLEG 的建议

我尝试将配置文件控制器中的显示操作更改为:

def show
    @profile = Profile.includes(:industries).find(params[:id])

  end

我得到相同的结果 - 没有显示任何行业信息。

解决方案

问题是我将加入 table 行业配置文件命名为。我认为它意味着行业独特。通过在模型中命名连接 table 使其与我在模式中给它的定义相匹配,解决了这个问题。

使用if代替unless并且industries是复数

<%- if @profile.industries.any? %>
  <%= @profile.industries.first.try(:sector) %>
<% end %>

编辑

在控制器中显示动作使用includes

@profile = Profile.includes(:industries).find(params[:id])