我试图在嵌套控制器中找到父对象,这样我就可以将后代资源与父对象关联起来,如下所示:
# 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方法。
请忽略已注释的代码,因为我也在积极寻找答案。
提前致谢。
以下是相关文件和服务器日志。
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
答案 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,然后你可以找到与该大学相关的团队。