将foreign_key值传递给Rails控制器的更好方法

自从我开始深入挖掘forms,联想,哈希,符号以来已经差不多一个星期……但似乎没有你的帮助我无法解决这个难题。

我正在开展一个展示不同画廊内容的项目。 基本思想是当用户看到画廊的名称(名称是链接)时能够点击所选择的名称。 然后显示属于此库的所有图像。 在底部应该有一个链接“在此库中添加图像”。

我的模特:

class Gallery < ActiveRecord::Base attr_accessible :name has_many :pictures end class Picture < ActiveRecord::Base attr_accessible :image belongs_to :gallery end 

我在gallery_id上为’pictures’表创建了索引。

我的大问题出现在这里,如何将gallery_id传递给控制器​​的动作’new’。 正如我在“使用Rails进行敏捷Web开发”中看到的那样,它可能是:
@ gallery.id)%>

在这种情况下,似乎foreign_key:gallery_id公开在浏览器的URL栏中。 第二个问题是:gallery_id可用于控制器的“新”function,但“创建”function“消失”(导致错误“无法找到没有ID的图库”)。 当我在图片的_form中添加隐藏字段时,问题就消失了,在我的情况下:

  
params[:gallery_id] %>

以下是我在“图片”控制器中的定义:

 def new @gallery=Gallery.find(params[:gallery_id]) @picture=@gallery.pictures.build end def create @gallery = Gallery.find(params[:gallery_id]) @picture = @gallery.pictures.new(params[:picture]) if @picture.save redirect_to(@picture, :notice => 'Picture was successfully created.') else redirect_to(galleries ,:notice => 'Picture was NOT created.') end end 

最后,show.html.erb中的link_to定义为画廊:

  
@gallery.id) %>

这是提交图像之前的调试输出:—!map:ActiveSupport :: HashWithIndifferentAccess gallery_id:“6”​​动作:新控制器:图片

并在提交“创建”按钮后(提出exception):

 {"utf8"=>"✓", "authenticity_token"=>"IGI4MfDgbavBShO7R2PXIiK8fGjkgHDPbI117tcfxmc=", "picture"=>{"image"=>"wilsonblx.png"}, "commit"=>"Create"} 

如你所见,“pictures”哈希中没有“gallery_id”。

向您总结我的问题:

  1. 有没有办法在没有hidden_​​field的情况下传递foreign_key?

  2. 我能以某种方式隐藏传递URL栏中显示的外键表单吗?

  3. 是否有使用’link_to’传递参数的替代方法?

谢谢 。

您可能需要考虑在嵌套资源上阅读Rails指南:

http://guides.rubyonrails.org/routing.html#nested-resources

简而言之:

的routes.rb

 resources :galleries do resources :pictures do end # Generates the routes: /galleries/:gallery_id/pictures 

pictures_controller.rb

 def new @gallery = Gallery.find(params[:gallery_id]) @picture = Picture.new end def create @gallery = Gallery.find(params[:gallery_id]) # gallery_id is passed in the URL @picture = @gallery.build(params[:picture]) if @picture.save # success else # fail end end 

图片/ new.html.erb

 <%= form_for [@gallery, @picture] do |f| %> 
<%= f.hidden_field :gallery_id , :value=>params[:gallery_id] %> <%= f.label :image %>
<%= f.file_field :image %>
<%= f.submit "Create" %>
<% end %>

好的,所以gallery_id仍然通过URL,但我真的没有看到任何错误。 你必须把它传递到某个地方,对吧? 你真正只有3个理智的选择:传递它的地方:隐藏字段,查询字符串参数,或者隐藏在URL(嵌套资源)中。 在3中,后者是恕我直言最干净的方法。

如果你想让事情变得更加容易,我强烈建议你研究一下Jose Valim的inheritance资源gem,它可以为你解决很多这样的漏洞:

https://github.com/josevalim/inherited_resources

您无需在RESTful路由中使用数字ID。 查看permalink_fu,并使用:permalink字段而不是:id来引用每个库资源。

 /galleries/louvre /galleries/moma/382 

 ... new_picture_path(:gallery_id => @gallery.permalink) 

这里的关键是使用一个符号,唯一的密钥,而不是ID,永久链接是非常好的。

您可以选择在as:id中传递永久链接并更新控制器操作以期望它。