我有一个Section模型,其中Section可以是另一个Section(子部分)的父级。
这是我的模特:
class Section < ActiveRecord::Base
has_many :exercises
has_one :parent_link,
:foreign_key => 'subsection_id',
:class_name => 'SectionLink',
:dependent => :destroy
has_one :parent, :through => :parent_link
has_many :subsection_links,
:foreign_key => 'parent_id',
:class_name => 'SectionLink',
:dependent => :destroy
has_many :subsections, :through => :subsection_links
attr_accessor :parent_id
def to_param
"#{id}-#{description.parameterize}"
end
def self.search(search)
if search
find(:all, :conditions => ['description LIKE ?', "%#{search}%"])
else
find(:all)
end
end
end
关联模型:
class SectionLink < ActiveRecord::Base
belongs_to :parent, :class_name => 'Section'
belongs_to :subsection, :class_name => 'Section'
end
我的控制器:
class SectionsController < ApplicationController
# GET /sections
# GET /sections.json
def index
@sections = Section.order("subsections_count DESC").search(params[:search])
respond_to do |format|
format.html # index.html.erb
end
end
# GET /sections/1
# GET /sections/1.json
def show
@section = Section.find(params[:id])
@subsections = @section.subsections
@exercises = @section.exercises
respond_to do |format|
format.html # show.html.erb
format.json { render json: @section }
end
end
# GET /sections/new
# GET /sections/new.json
def new
@section = Section.new
@section.parent_id = params[:parent]
respond_to do |format|
format.html # new.html.erb
format.json { render json: @section }
end
end
# GET /sections/1/edit
def edit
@section = Section.find(params[:id])
end
# POST /sections
# POST /sections.json
def create
@section = Section.new(params[:section])
@parent = @section.build_parent(:parent_id => @section.parent_id) unless @section.parent_id.empty?
respond_to do |format|
if @section.save
format.html { redirect_to @section, notice: 'Section was successfully created.' }
format.json { render json: @section, status: :created, location: @section }
else
format.html { render action: "new" }
format.json { render json: @section.errors, status: :unprocessable_entity }
end
end
end
# PUT /sections/1
# PUT /sections/1.json
def update
@section = Section.find(params[:id])
respond_to do |format|
if @section.update_attributes(params[:section])
format.html { redirect_to @section, notice: 'Section was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @section.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sections/1
# DELETE /sections/1.json
def destroy
@section = Section.find(params[:id])
@section.destroy
respond_to do |format|
format.html { redirect_to sections_url }
format.json { head :no_content }
end
end
end
父ID通过隐藏字段输入,格式为:
<%= form_for(@section) do |f| %>
<% if @section.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@section.errors.count, "error") %> prohibited this section from being saved:</h2>
<ul>
<% @section.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<%= f.hidden_field :parent_id, :value => @section.parent_id %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
我正在
undefined method 'build_parent' for #<Section:0xb4f1764c>
有没有更好的方法来建模这种关联?为什么build_parent未定义?
更新
现在使用以下控制器代码:
@section = Section.new(params[:section])
unless @section.parent_id.empty?
@parent = Section.find(@section.parent_id)
@section.parent = @parent
end
寻找有关如何改进的建议,以及之前为什么不起作用的建议......
答案 0 :(得分:3)
您正在寻找self join。
class Section < ActiveRecord::Base
has_many :subsections, :class_name => "Section"
belongs_to :parent_section, :class_name => "Section",
:foreign_key => "parent_id"
end