环境: ruby 1.9.3, rails 3.2.6
关于1对N的表关联,在Rails官网上关于Post和comment的例子,有很详细的例子
它是这样的,一条商品有多条评论,都在一个页面展现,后台实现就是先得到这个商品的id
以此来设置comments表的外键,而且一条post和多条comments是在同一个页面中展示的
,首先拿到post的id,在根据post_id查找comments,随后展示出来。
但这不是我想要的,有些一对多关系不一定展示在一个页面,比如:公司某部门分为多个大区,
而每个大区负责几个地区的产品,这样,大区和地区就有了1对多的关系,后台维护想这样做
在创建area的时候,给他指定所属的大区region,原理实际上和post,comments一致,下面是具体
操作步骤:
1.生成脚手架
大区-region 和 地区-area
rails g scaffold region name:string rails g scaffold area name:string region:references
在area的模型model文件中增加如下一句,指定级联删除,在删除region的时候,会同时删除与之关联的areas
has_many :areas , :dependent => :destroy
2. 修改areas/_form.html.erb文件
<div class="field"> <%= select("region", "region_id", Region.all.collect {|p| [ p.name, p.id ] }, {:prompt => '--请选择大区--'})%> </div>
这句话的意识是当进入到创建area的界面后,从数据库中获取所有的regions
<div class="field"> <select id="region_region_id" name="region[region_id]"><option value="">--请选择大区--</option> <option value="2">区1</option> <option value="4">区2</option> <option value="5">区3</option> </div>
页面上显示的是region的名称,而value则是region对应的id,也就是area在创建的时候需要保存的外键信息region_id
3. 修改areas/show.html.erb文件,显示region对应的名称
<b>Region:</b> <%= @area.region.name %>
4. 修改areas/index.html.erb文件,同上
<td><%= area.region.name %></td>
5. 创建地区的时候,因为地区为多的一端,
存储着region_id, 在存储的时候必须把对应的region_id找到
首先根据名称找到该地区所在的大区,就可以找到对应的region_id了
修改 controller/areas_controller.rb文件
def create @region = Region.find(params[:region][:region_id]) @area = @region.areas.create(params[:area]) respond_to do |format| if @area.save format.html { redirect_to @area, notice: 'Area was successfully created.' } format.json { render json: @area, status: :created, location: @area } else format.html { render action: "new" } format.json { render json: @area.errors, status: :unprocessable_entity } end end end
到此刷新页面就可以了~
关于select的其他用法:http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html