ActiveRecord :: RecordNotFound - 在后代类中' associated_controller#指数

时间:2013-12-03 03:16:14

标签: ruby-on-rails ruby-on-rails-3

我试图在嵌套控制器中找到父对象,这样我就可以将后代资源与父对象关联起来,如下所示:

# teams_controller.rb <snippet only>

def index
  @university = Univeresity.find(params[:university_id])
  @teams = @university.teams
end

当我按照上面的代码段调用find(params[:university_id])时在teams_controller.rb的第6行,我收到了ActiveRecord :: RecordNotFound - 找不到没有ID的大学。

我不仅对修复此问题感兴趣,而且还可以更好地理解查找对象而无需输入University.find(1)值,因为我授予Admin添加大学的权限。

Rails指南中说明了网站中两种参数的以下内容:

  

3参数

     

您可能希望访问用户或其他人发送的数据   控制器动作中的参数。有两种   Web应用程序中可能的参数。第一个是参数   作为URL的一部分发送,称为查询字符串参数。该   查询字符串是URL中“?”之后的所有内容。第二种类型   参数通常称为POST数据。此信息   通常来自用户填写的HTML表单。   它被称为POST数据,因为它只能作为HTTP的一部分发送   POST请求。 Rails不会对查询字符串进行任何区分   参数和POST参数,两者都在参数中提供   控制器中的哈希:

它继续向下,解释说params散列是HashWithIndifferentAccess的一个实例,它允许交替使用符号和字符串作为键。

根据我上面的内容,我的理解是Rails识别这两个参数(URL和POST)并将它们存储在相同的哈希(params)中。

我可以将params哈希传递给任何控制器操作中的find方法,还是只创建/更新操作?我还有兴趣找到一个可读/可查看的资源,以了解在控制器的“更新”操作中调用的update_attributes方法。

请忽略已注释的代码,因为我也在积极寻找答案。

提前致谢。

以下是相关文件和服务器日志。

的WEBrick

enter image description here

teams_controller.rb

class TeamsController < ApplicationController
  # before_filter :get_university
  # before_filter :get_team

  def index
    @university = University.find(params[:univeristy_id])
    @teams = @university.teams
  end

  def new
    @university = University.find(params[:university_id])
    @team = @university.teams.build
  end

  def create
    @university = University.find(params[:university_id])
    @team = @university.teams.build(params[:team])
    if @team.save
      redirect_to [@university, @team], success: 'Team created!'
    else
      render :new, error: 'There was an error processing your team'
    end
  end

  def show
    @university = University.find(params[:university_id])
    @team = @university.teams.find(params[:id])
  end

  def edit
    @university = University.find(params[:university_id])
    @team = @university.teams.find(params[:id])
  end

  def update
    @university = University.find(params[:university_id])
    @team = @university.teams.find(params[:id])
    if @team.update_attributes(params[:team])
      redirect_to([@university, @team], success: 'Team successfully updated')
    else
      render(:edit, error: 'There was an error updating your team')
    end
  end

  def destroy
    @university = University.find(params[:university_id])
    @team = @university.teams.find(params[:id])
    @team.destroy
    redirect_to university_teams_path(@university)
  end

  private 
  def get_university
    @university = University.find(params[:university_id]) # can't find object without id
  end

  def get_team 
    @team = @university.teams.find(params[:id])
  end
end

team.rb

class Team < ActiveRecord::Base
  attr_accessible :name, :sport_type, :university_id

  has_many :home_events, foreign_key: :home_team_id, class_name: 'Event'
  has_many :away_events, foreign_key: :away_team_id, class_name: 'Event'
  has_many :medias, as: :mediable
  belongs_to :university

  validates_presence_of :name, :sport_type

  # scope :by_university, ->(university_id) { where(team_id: team_id).order(name: name) }
  # scope :find_team, -> { Team.find_by id: id }
  # scope :by_sport_type, ->(sport_type) { Team.where(sport_type: sport_type) }
  # scope :with_university, joins: :teams 
  # def self.by_university(university_id)
  #   University.where(id: 1)
  #   University.joins(:teams).where(teams: { name: name })
  # end

  def self.by_university
    University.where(university_id: university_id).first
  end

  def self.university_join
    University.joins(:teams)
  end

  def self.by_sport_type(sport_type)
    where(sport_type: sport_type)
  end

  def self.baseball
    by_sport_type('Baseball/Softball')
  end
end

university.rb

  class University < ActiveRecord::Base
  attr_accessible :address, :city, :name, :state, :url, :zip

  has_many :teams, dependent: :destroy

  validates :zip, presence: true, format: { with: /\A\d{5}(-\d+)?\z/ },
            length: { minimum: 5 }
  validates_presence_of :name, :address, :city, :state, :url

  scope :universities, -> { University.order(name: 'ASC') }
  # scope :by_teams, ->(university_id) { Team.find_by_university_id(university_id) }
  # scope :team_by_university, ->(team_id) { where(team_id: team_id).order(name: name)}

  def sport_type
    team.sport_type
  end
end

views / teams / index.html.erb

Placed in gists for formatting reasons

rake路由输出:(在公共要点中)

enter link description here

rails console

enter image description here

1 个答案:

答案 0 :(得分:2)

你不会想要两者兼得:

resources :universities  #lose this one

resources :universities do 
  resources :teams 
end

至于params ......你必须给一个参数。因此,当您转到http://localhost:3000/teams时,默认情况下没有参数。如果你转到http://localhost:3000/teams/3然后转到params[:id] = 3,这将拉动你的第三个团队。

请记住索引的命名法。团队的索引行动将列出所有团队。他们都是。那里没有一所大学,你究竟想找到什么?对于你的大学校长来说,如果有的话,你有:

def show
  @university = University.find(params[:id])
  @teams = @university.teams
end

所以,地址栏会显示http://localhost:3000/universities/23,对吧? params [:id] = 23,然后你可以找到与该大学相关的团队。