RAILS: Как генерировать ссылки для модели Grandchild, используя нотацию [@Grandparent, @Parent] (Grandparent отображается как Nil)
Я сталкиваюсь со следующей ошибкой при попытке показать, изменить, удалить или добавить район:
undefined method `state_path' for #<#<Class:0x007f93a9e9df88>:0x007f93af11f8d8>
Я ожидаю, что он сгенерирует ссылку country_state_path, так как у меня есть link_to 'Back', [@country, @state]
но по какой-то причине он только дает мне state_path. Если я использую точку-нотацию вместо выполнения @country.state, я получаю ошибку nilClass.
Я использую древовидную структуру для своих моделей:
Country
State
District
Если я вхожу в country_state_path все работает нормально. Но я бы предпочел ввести его, используя обозначение модели, так как это работает в моей модели состояния.
(Я использую правильные термины? Пожалуйста, исправьте, если нет, я все еще новичок в Rails)
КОД
Модель района
class District < ActiveRecord::Base
validates_uniqueness_of :name, scope: :state_id
before_destroy :check_for_schools
belongs_to :state
#has_many :schools, :order => 'name'
private
def check_for_schools
=begin
if schools.count > 0
self.errors[:base] << "Cannot delete district while schools exist."
return false
end
=end
end
end
Районный контролер
class DistrictsController < ApplicationController
# Allows JSON Queries
skip_before_filter :verify_authenticity_token
before_action :set_district, only: [:show, :edit, :update, :destroy]
before_filter :load_state
# GET /districts
# GET /districts.json
def index
@districts = @state.districts.all(:order => 'name ASC')
end
# GET /districts/1
# GET /districts/1.json
def show
end
# GET /districts/new
def new
@district = @state.districts.new
end
# GET /districts/1/edit
def edit
@state.districts.find(params[:id])
end
# POST /districts
# POST /districts.json
def create
@district = @state.districts.new(district_params)
respond_to do |format|
if @district.save
format.html { redirect_to [@country,@state,@district], notice: 'District was successfully created.' }
format.json { render action: 'show', status: :created, location: @district }
else
format.html { render action: 'new' }
format.json { render json: @district.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /districts/1
# PATCH/PUT /districts/1.json
def update
respond_to do |format|
if @district.update(district_params)
format.html { redirect_to [@state, @district], notice: 'District was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @district.errors, status: :unprocessable_entity }
end
end
end
# DELETE /districts/1
# DELETE /districts/1.json
def destroy
@district = @state.district.find(params[:id])
respond_to do |format|
if @district.destroy
format.html { redirect_to @state }
format.json { head :no_content }
else
format.html { redirect_to( @state, :notice => 'Unable to delete a state that has districts.') }
format.json { render json: @district.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_district
@district = District.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def district_params
params.require(:district).permit(:name, :state_id)
end
def load_state
@state = State.find(params[:state_id])
end
end
Район "Шоу" Посмотреть
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @district.name %>
</p>
<p>
<strong>State:</strong>
<%= @district.state_id %>
</p>
<%= link_to 'Edit', edit_country_state_district_path(@country, @state, @district) %> |
<%= link_to 'Back', [@country, @state] %>
Линия, которая не работает, является "link_to 'Back', [@country, @state]
,
2 ответа
Вам нужно будет вручную установить @country в ваших методах show/edit/destroy, так как @country равен nil.
Примечание, хотя. Как правило, лучше всего вкладывать только два вглубь. Так:
Country
State
State
District
Я знаю. Я знаю. Не стреляйте в курьера. Просто передаю информацию.
Поэтому мне нужно структурировать свои маршруты следующим образом:
NetworkManager::Application.routes.draw do
root to: "countries#index"
resources :countries do
resources
end
resources :states do
resources :districts
end
end
Вместо:
NetworkManager::Application.routes.draw do
root to: "countries#index"
resources :countries do
resources :states do
resources :districts
end
end
end
Итак, вот моя конечная цель, может быть, у вас есть лучший способ сделать это...
Мы настраиваем школы по всей стране, и у каждой школы есть множество различных сетевых устройств. Реальная цель этого состоит в том, чтобы отследить, что информация сети для каждой школы, но я хочу иметь возможность организовать ее по странам -> Штатам -> Районы -> Школы -> Сети -> Устройства.
Если я хочу сделать это, я думаю, что лучше сделать
Countries
States
States
Districts
Districts
Schools
Schools
Networks
Networks
Devices
Я хочу, чтобы человек, вводящий информацию, мог легко сказать, что это устройство связано с этой школой А. И, возможно, даже можно легко подключить устройство к району на случай, если его придется перенести в другую школу.