【问题标题】:Rails deeply nested resources alternative to accessing paramsRails 深度嵌套资源替代访问参数
【发布时间】:2014-11-22 04:28:19
【问题描述】:

我在事件中有一个事件模型和一个 Q+A 模型。

我是 Rails 新手,所以不确定是否有其他方法可以做到这一点

现在,在 show.html.erb 的活动中,我有一个表单来发布问题,每个问题都有一个表单来发布答案

现在的路线是这样的

  resources :events do
    resources :event_questions, only: [:create, :destroy]
  end

当您在我的show.html.erb 中创建一个问题时,它正在通过EventQuestionsController 进行路由,我通过参数访问 event_id。我的event_answer 是否必须以同样的方式进行操作?

我的意思是,我是否必须将 event_answers 嵌套在 event_questions 中。我需要知道 event_id 和 event_question_id。

如果这是访问参数的唯一方法。会是这样吗?

  resources :events do
    resources :event_questions, only: [:create, :destroy] do
       resources :event_answers, only: [:create, :destroy]
    end
  end

event_questions_controller.rb

def create
    @event_question = EventQuestion.new(event_question_params)
    if @event_question.save
        event = Event.find(params[:event_id])
        @event_question.event = event
        redirect_to event
    else
        redirect_to :back
    end
end

show.html.erb

<%= form_for(@event_question, :url => event_event_questions_path(@event)) do |f|  %>
# form stuff
<% end %>

我开始将我的答案表改成这个

<%= @event.event_questions.each do |q| %>
    <%= q.question %>
    <%= q.fields_for :answers do |a| %>
        <%= a.label :answer %>
        <%= a.text_field :answer %>
        <%= a.submit "Answer" %>
    <% end %>
<% end %>

【问题讨论】:

  • 我发布了一个可能对您有所帮助的答案,但没有看到您的控制器和您视图的相关部分,可能很难提供帮助。但是,您永远不需要直接访问 id 参数,因为您的代码应该能够为您确定它。请参阅下面的答案以了解我所指的内容。
  • 我添加了我的event_questions_controller 让您了解我之前在做什么。我打算用我的 event_answers_controller 做类似的事情。我正试图围绕表单如何查找我的 event_answers。另外,我将如何访问我的create 中的变量。我可以做和你展示的一样的事情吗?你可以忽略奇怪的东西 b/c 我没有为这个项目使用 sql DB。

标签: ruby-on-rails nested-attributes params rails-routing nested-resources


【解决方案1】:

您不需要直接访问参数来创建嵌套记录。例如,如果在您的 event#new 操作中,您可能会有类似

@event = Event.new

3.times do
  question = @event.questions.build
  5.times do
    question.answers.build
  end
end

这将创建一个新事件并将您带到新页面。在您的新页面中,您应该有嵌套字段来创建和更新嵌套模型。

在表单中,您可以使用fields_for 访问关联模型的记录到该event 记录。在new 行动案例中,我们构建了 3 个问题,每个问题有 5 个答案。

<%= simple_form_for @event do |f| %>
  <%= f.input :attribute1 %>
  <%= f.input :attribute2 %>
  <%= f.fields_for :questions do |builder| %>
    <%= render 'questions', f: builder %>
  <% end%>
<% end %>

我通常喜欢在进行嵌套关联时使用部分,但如果您想将其全部保存在一个文件中(见下文),它看起来像这样。

<%= simple_form_for @event do |f| %>
  <%= f.input :attribute1 %>
  <%= f.input :attribute2 %>
  <%= f.fields_for :questions do |q| %>
    <%= q.input :question_text %>
    <%= q.fields_for :answers do |a| %>
      <%= a.input :answer_text %>
    <% end %>
  <% end%>
<% end %>

在您的show 操作中,您可能有这样的事情

@event = Event.find(params[:id])
@questions = @event.questions
@answers = @question.answers if @questions

从这里,您分配了三个实例变量,并且能够访问与您的事件和问题相关的记录。

【讨论】:

  • 我添加了一些表单示例和控制器信息。我不明白的是..如果我的路线没有嵌套,我如何获得事件ID等?当我发布到create 操作时
【解决方案2】:

在一些帮助下,我从一些 kobaltz 答案和其他一些帮助中得出了这个答案。

另一种方法是将信息放在隐藏字段中并将其传递给控制器​​

   <%= @event.event_questions.each do |q| %>
        <%= q.question %><br>
        <% q.event_answers.each do |a| %>
            <%= a.answer %>
        <% end %>
        <%= form_for(EventAnswer.new) do |f| %>
            <%= hidden_field_tag :event_question_id, q.id %>
            <%= hidden_field_tag :event_id, @event.id %>
            <%= f.label :answer %>
            <%= f.text_field :answer %>
            <%= f.submit "Answer" %>
        <% end %>
    <% end %>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多