【问题标题】:Rails params[:id] are not been sentRails 参数 [:id] 未发送
【发布时间】:2015-02-06 17:44:26
【问题描述】:

导轨 4

我有一个帐户和注释模型。我正在尝试保存与该帐户相关的注释。

笔记模型

class Note < ActiveRecord::Base
  belongs_to :account
end

帐户模型

class Account < ActiveRecord::Base
  ...
  has_mamy :notes
end

路线:

 resources :accounts
 resources :notes

 get 'accounts/:id/new_note'  => 'notes#new'

notes_controller.rb

def new
  @note            = Note.new
  @note.account_id = params[:id]

  respond_with(@note)
end


def create
  @note = Note.new(note_params)
  @note.save

  repond_with(@note)
end

private
  def note_params
     params.require(:note).permit(:title, :description, :account_id, :opportunity_id, :created_by, :updated_by)
  end
end

当我 GET ".../accounts/1/new_note" 并 POST 请求时,注释会被保存,但 @note.account_id = nil。

为什么?

在我的其他模型机会中,具有类似的行为并且一切正常。

【问题讨论】:

  • 您确定您不是在寻找@note.account_id = params[:account_id] 吗?为什么您使用自定义路由而不是嵌套资源?
  • 我真的不知道嵌套资源。我会试一试。但我想了解为什么这种方式不适用于笔记。它应该是 params[:id] 而不是 params[:account_id] 因为这是我在 Route.rb 上声明它的方式据我了解,如果我更改为您提出的解决方案 @note.account_id = params[:account_id ] 我的路线应该看起来像这样 get 'accounts/:account_id/new_note' 我刚刚尝试过但也不起作用
  • 这对我来说似乎有点混乱。您如何执行 POST 请求?在您发布的路线中,没有任何内容涉及定义您的方法的 notes_controller.rb。
  • POST 是通过标准 POST /notes notes#create 完成的。也许我忘了澄清有资源:notes
  • 所以我假设您的帐户控制器中有new_note 操作?那是什么样子的?也许您希望 accounts_controller.rb 中的 new_note 操作看起来像 notes_controller 中的 new 操作?

标签: ruby-on-rails ruby-on-rails-4 routes params


【解决方案1】:

您可以采取两种策略来解决这个问题。

选项 1。最好的解决方案是使用嵌套属性。您的用户将拥有一种表单,为什么可以使用该表单在一种用户体验中为两种模型创建数据。详情请查看RailsGuides

在 app/models/account.rb 中

class Account < ActiveRecord::Base # as usual
  has_many :notes
  accepts_nested_attributes_for :notes
end

在您的 app/controllers/accounts_controller.rb 中更新“accounts_params”方法

private

def accounts_params
  params.require(:accounts).permit(--all the stuff you already have--, 
                                   notes_attributes: [
                                        :id, 
                                        :title, 
                                        :description, 
                                        :account_id, 
                                        :opportunity_id
                                   ])
end

同样在 app/controllers/accounts_controller.rb 中,您还需要再做两处小改动 - 在“new”和“edit”方法中增加一行:

def new
  @account = Account.new
  @account.notes.build # adds an empty note to your new account.
end

def edit
  @account = Account.find(params[:id])
  @account.notes.build # add a new empty note
end

我假设您的项目中有一个 views/accounts/_form.html.erb。假设您希望合并帐户和备注的用户界面,您可以扩展您的 _form.html.erb 文件以包含以下内容(例如,这可能位于您的提交按钮之前):

<%=f.fields_for :notes do |note| %>
  <div>
    <%= note.label :title %>
    <%= note.text_field :title %>
  </div>
  <div>
    <%= note.label :description %>
    <%= note.text_area :description, rows: 4 %>
  </div>
<% end %>

然后您就可以省去自定义路由设置和可能的 notes_controller(除非您出于其他原因需要它)。

选项 2。您可以有一个专用的 notes_controller 来处理创建和更新请求,您可以对其进行微调以将用户重定向回帐户页面。不是一个“坏”的方式,但它的缺点是“更多”代码和用户遵循的第二个过程 - 管理帐户,并单独管理笔记。就是说,这是你可以做到的。

a) 创建一个带有典型“create”和“update”方法的notes_controller。

b) 在这些方法结束时,它们可能会执行以下操作:

redirect_to @note

您可以将其更改为:

redirect_to @note.account

这会将您带到 localhost:3000/accounts/123(假设注释附加到注释编号 123。

c) 您将构建一个 app/views/notes/_form.html.erb 文件作为自包含表单。

d) 在您的 app/views/accounts/show.html.erb 文件中,您将在页面底部添加一个新面板,其中列出了特定帐户的所有注释。

# app/views/accounts/show.html.haml
<h1>Account # <%= @account.id %></h1>
...
<p>
  <=% link_to 'back', accounts_url %> | <%= link_to 'edit', edit_account_url(@account) %>
</p>

<h2>Notes</h2>
<table>
  <tr>
    <th>Title</th>
    <th>Description</th>
  </tr>
  <% @account.notes.each do |note| %>
    <tr>
      <td><%= note.title %></td>
      <td><%= note.description %></td>
    </tr>
  <% end %>
  <%= form_for @account.notes.build do |f| %>
    <tr>
      <td><%= f.text_field :title %></td>
      <td><%= f.text_area :description, rows: 4 %></td>
      <!-- add whatever fields you want in here -->
    </tr>
    <tr><td colspan="4"><%= f.submit 'Save' %></td></tr>
   <% end %>
</table>

要完成这项工作,您在路线文件中只需要:

# config/routes.rb
resources :accounts # as before
resources :notes, only: [:create, :update]

其余的应该由 Rails 处理。

无论使用哪种方式,您都可能需要花点时间为您的用户提供“编辑”和“删除”功能。画一些草图,然后问你的客户/豚鼠用户什么对他们来说更直观。

【讨论】:

  • 好的!这就是嵌套资源的外观。资源 :accounts 做资源 :notes 结束。我在表单中收到此错误,NoMethodError in Notes#new, undefined method `notes_path' for...
  • 我已经重写了我的原始帖子,以便您更清楚地了解如何进行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多