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

时间:2016-01-09 22:21:27

标签: ruby-on-rails join associations has-and-belongs-to-many

我正在尝试在Rails 4中创建一个应用程序。

我有一个行业模型和个人资料模型。

我的行业表有:

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连接表关联来执行此操作。

我目前的尝试是:

<% 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的建议

我尝试将配置文件控制器中的show动作更改为:

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

  end

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

解决方案

问题在于我将连接表行业配置文件命名为。我认为它意味着行业奇异。通过在模型中命名连接表来解决此问题,以便它与我在模式中给出的定义相匹配。

1 个答案:

答案 0 :(得分:1)

使用if而不是unlessindustries是复数

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

修改

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

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