将foreign_key 值传递给Rails 控制器的更好方法 [英] The better way to pass the foreign_key value to the Rails controller

查看:26
本文介绍了将foreign_key 值传递给Rails 控制器的更好方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我开始深入挖掘表单、关联、散列、符号以来,已经快一周了……但如果没有你的帮助,我似乎无法解决这个难题.

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

我的模型:

 class Gallery 

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

我的大问题出现在这里,如何将 gallery_id 传递给控制器​​的动作 'new' .正如我在使用 Rails 进行敏捷 Web 开发"中所见,它可能是:
<%= link_to '在此处添加图片...',new_picture_path(:gallery_id=>@gallery.id) %>

在这种情况下,foreign_key :gallery_id 似乎暴露在浏览器的 URL 栏中.第二个问题是 :gallery_id 可用于控制器 '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 class="actions"><%= f.submit "创建" %>

<%结束%>

这是我在图片"控制器中的定义:

def new@gallery=Gallery.find(params[:gallery_id])@picture=@gallery.pictures.build结尾定义创建@gallery = Gallery.find(params[:gallery_id])@picture = @gallery.pictures.new(params[:picture])如果@picture.saveredirect_to(@picture, :notice => '图片创建成功.')别的redirect_to(画廊,:notice => '图片未创建.')结尾结尾

最后是 show.html.erb 中用于画廊的 link_to 定义:

<% for 图片 in selpics(@gallery) %><div id="拇指" ><%= image_tag 图片.image %>

<%结束%><%= link_to '在此处添加图片...',new_picture_path(:gallery_id=>@gallery.id) %>

这是提交图像前的调试输出:--- !map:ActiveSupport::HashWithIndifferentAccess画廊 ID:6"动作:新控制器:图片

并在提交创建"按钮后(引发异常):

{"utf8"=>"✓","authenticity_token"=>"IGI4MfDgbavBShO7R2PXIiK8fGjkgHDPbI117tcfxmc=","图片"=>{"image"=>"wilsonblx.png"},提交"=>创建"}

如您所见,图片"哈希中没有像gallery_id"这样的东西.

总结我给你的问题:

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

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

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

谢谢.

解决方案

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

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

简而言之:

routes.rb

资源:画廊做资源:图片做结尾# 生成路线:/gallery/:gallery_id/pictures

pictures_controller.rb

def new@gallery = Gallery.find(params[:gallery_id])@picture = Picture.new结尾定义创建@gallery = Gallery.find(params[:gallery_id]) #在URL中传递gallery_id@picture = @gallery.build(params[:picture])如果@picture.save# 成功别的# 失败结尾结尾

图片/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 class="actions"><%= f.submit "创建" %>

<%结束%>

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

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

https://github.com/josevalim/inherited_resources

It's been almost a week since I've began to dig deeper in forms , associations , hashes , symbols... But it seems I cannot solve the puzzle without your help .

I am working on a project for displaying different galleries content . The basic idea is when the user sees the names of galleries (names are links ) to be able to click on chosen one. Then all the images ,that belong to this gallery , are displayed . On the bottom there should be a link "Add image in this gallery" .

My models :

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


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

I have created index on gallery_id for the 'pictures' table .

My big problem appears here , how to pass the gallery_id to the controller's action 'new' . As I've seen in "Agile web development with Rails" it could be :
<%= link_to 'Add a picture here...',new_picture_path(:gallery_id=>@gallery.id) %>

As it seems in this case the foreign_key :gallery_id is exposed in the URL bar of the browser . The second problem is that :gallery_id is available for the controller 'new' function , but "disappears" for the 'create' function (causing an error " Couldn't find Gallery without an ID ") . The problem is gone when I add a hidden field in the _form for pictures , in my case :

<%= 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 %>

Here are my definitions in the 'pictures' 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

And finaly the link_to definition in show.html.erb for galleries:

<% 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) %>

Here is the debug output before submitting the image : --- !map:ActiveSupport::HashWithIndifferentAccess gallery_id: "6" action: new controller: pictures

and after submitting the 'create' button (with exception raised ) :

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

As you see , there is nothing like "gallery_id" in the "pictures" hash .

Summarizing my questions to you :

  1. Is there a way to pass the foreign_key without hidden_field ?

  2. Could I hide somehow passing the foreign key form showing in the URL bar ?

  3. Is there an alternative on passing arguments using 'link_to' ?

Thank you .

解决方案

You may want to consider reading the Rails Guide on nested resources:

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

In a nutshell:

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

pictures/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 %>

Ok, so the gallery_id is still passed through the URL, but I don't really see anything wrong with that. You have to pass it somewhere, right? You really only have 3 sane choices on where to pass it: a hidden field, as a querystring parameter, or tucked away inside the URL (nested resource). Of the 3, the latter is IMHO the cleanest method.

If you want to make things even easier on yourself, I highly recommend looking into Jose Valim's Inherited Resources gem that takes care of a lot of this boilerplate nastiness for you:

https://github.com/josevalim/inherited_resources

这篇关于将foreign_key 值传递给Rails 控制器的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆