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])
我正在尝试在 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])