ruby-on-rails - 将foreign_key 值传递给Rails Controller 的更好方法

标签 ruby-on-rails associations foreign-key-relationship link-to

自从我开始深入研究表格、关联、散列、符号以来,已经快一个星期了……但如果没有你的帮助,我似乎无法解开这个谜题。

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

我的模型:

 class Gallery < ActiveRecord::Base
attr_accessible  :name
has_many :pictures 
 end


class Picture < ActiveRecord::Base 
attr_accessible  :image 
belongs_to :gallery
 end

我已经为 'pictures' 表在 gallery_id 上创建了索引。

我的大问题出现在这里,如何将 gallery_id 传递给 Controller ​​的 Action 'new' 。正如我在“使用 Rails 进行敏捷 Web 开发”中看到的那样,它可能是:
<%= link_to '在此处添加图片...',new_picture_path(:gallery_id=>@gallery.id) %>

在这种情况下,foreign_key :gallery_id 似乎暴露在浏览器的 URL 栏中。第二个问题是 :gallery_id 可用于 Controller 'new' 函数,但“消失”用于 'create' 函数(导致错误“无法找到没有 ID 的画廊”)。
当我在 _form 中为图片添加隐藏字段时,问题就消失了,就我而言:
<%= form_for(@picture)   do |f| %>
<div class="field"> 
      <%= f.hidden_field :gallery_id , :value=>params[:gallery_id] %>
<%= f.label :image %><br />
<%= f.file_field :image %>
</div>

<div class="actions">
<%= f.submit "Create" %>
</div>
<% end %>

这是我在“图片” Controller 中的定义:
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 定义:
<% for picture in selpics(@gallery) %>
 <div id= "thumb" > 
 <%= image_tag picture.image %>
 </div>
<% end %>

 <%= link_to 'Add a picture here...',new_picture_path(:gallery_id=>@gallery.id) %>

这是提交图像之前的调试输出:
--- !map:ActiveSupport::HashWithIndifferentAccess
画廊 ID:“6”
Action :新
Controller :图片

并在提交“创建”按钮后(引发异常):
{"utf8"=>"✓",
 "authenticity_token"=>"IGI4MfDgbavBShO7R2PXIiK8fGjkgHDPbI117tcfxmc=",
 "picture"=>{"image"=>"wilsonblx.png"},
 "commit"=>"Create"}

如您所见,“图片”哈希中没有像“gallery_id”这样的东西。

总结我给你的问题:
  • 有没有办法在没有 hidden_​​field 的情况下传递 foreign_key ?
  • 我可以隐藏以某种方式传递显示在 URL 栏中的外键表单吗?
  • 是否有使用 'link_to' 传递参数的替代方法?

  • 谢谢你 。

    最佳答案

    您可能需要考虑阅读有关嵌套资源的 Rails 指南:

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

    简而言之:

    路由文件

    resources :galleries do
      resources :pictures do
    end
    # Generates the routes: /galleries/:gallery_id/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| %>
      <div class="field"> 
        <%= f.hidden_field :gallery_id , :value=>params[:gallery_id] %>
        <%= f.label :image %><br />
        <%= f.file_field :image %>
      </div>
    
      <div class="actions">
        <%= f.submit "Create" %>
      </div>
    
    <% end %>
    

    好的,gallery_id 仍然通过 URL 传递,但我真的没有发现任何问题。你必须把它传递到某个地方,对吧?对于传递它的位置,您实际上只有 3 个明智的选择:隐藏字段、作为查询字符串参数或隐藏在 URL 中(嵌套资源)。在这 3 种方法中,恕我直言,后者是最干净的方法。

    如果您想让自己更轻松,我强烈建议您查看 Jose Valim 的 Inherited Resources gem,它为您处理了很多这种样板代码:

    https://github.com/josevalim/inherited_resources

    关于ruby-on-rails - 将foreign_key 值传递给Rails Controller 的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5207038/

    相关文章:

    ruby-on-rails - 在 Sinatra 中使用 ActiveRecord::SessionStore 进行 session

    ruby-on-rails - Rails 3 If 语句,,, IF XXX 至少等于一个 (Var1, Var2, Var3)

    ruby-on-rails - Ruby on Rails 协会

    mysql - 有趣的 Rails 协会挑战赛

    transactions - Sequelize - 在事务中插入多个关联实体失败

    mysql - 文件和图像的表结构

    ruby-on-rails - Rails 上的 OAuth(Twitter、Facebook、LinkedIn 等)

    ruby-on-rails - 带有嵌套资源 : update belongs_to association when creating new has_many 的 Rails 嵌套表单

    mysql - 关于MYSQL外键和孤行的问题

    mysql - 外键关系的最佳实践