简体   繁体   English

Rails嵌套资源-使用form_for部分创建和编辑2个级别

[英]Rails Nested Resources - create and edit 2 levels away with form_for in partial

Really racking my brain on this one. 真的让我的脑筋on肿了。 I'm relatively new to Rails and trying to do something that I'm sure is not too difficult. 我是Rails的新手,尝试做一些我确定不太困难的事情。

I have a model "Trip" which has many "Days" which has many "Activities" 我有一个模型“旅行”,其中有很多“天”,其中有很多“活动”

I am in the show.html.erb view of "Trip" and in this view, I am rendering a partial for a form that should allow me to create a new "Activity" to be associated with a "Day" or edit an existing "Activity" which already belongs to a "Day" 我在“旅行”的show.html.erb视图中,在此视图中,我正在渲染表单的部分内容,该表单应允许我创建一个与“日”相关联的新“活动”或编辑现有的已经属于“一天”的“活动”

How do I pass to the form_for in the form partial, the local variable of which "Day" I want to create the new "Activity" for. 如何在部分表单中传递给form_for,我要为其创建新的“活动”的局部变量“ Day”。 And using that same form partial, how can I retrieve the "Day" that the "Activity" is associated with? 并使用部分相同的表单,我如何检索与“活动”相关联的“日期”? Eventually these will be AJAX loaded objects. 最终,这些将是AJAX加载的对象。 I've googled for the past several hours and can't find any examples similar to this. 我已经搜索了过去几个小时,找不到类似的示例。 I really appreciate the help. 我非常感谢您的帮助。

routes.rb routes.rb

  resources :trips do
    resources :days    
  end

  resources :days do
    resources :activities
  end 

show.html.erb for the Trip 行程的show.html.erb

<div id="activities_list">
  <%= render :partial => "activities" %>
</div> 

<div id="activity_form">
  <%= render :partial => "/activities/form", :locals => { :activity => @activity}  %>
</div>

<div id="bottom">
<%= link_to 'Edit', edit_trip_path(@trip) %> |
<%= link_to 'Back', trips_path %>
</div>

_activities.html.erb partial _activities.html.erb部分

<h1><%= @trip.title %></h1>

<% @trip.days.each do |day| %>
<div id="blech_<%= day.id %>">
  <b><%= day.summary %></b>
      <% day.activities.each do |activity| %>
            <li id="activity_<%= activity.id %>"><%= link_to activity.address, edit_day_activity_path(day, activity), :remote => true  %></li>
      <% end %>
    <% end %>
  <%= link_to 'New Activity', new_day_activity_path(day), :remote => true %>
</div>
<% end %>

_form.html.erb partial I know that I need to be calling the day_activity_path with (@day,@activity) variables. _form.html.erb部分我知道我需要使用(@ day,@ activity)变量来调用day_activity_path。 but I don't know how to get the @day variable in here 但我不知道如何在这里获取@day变量

  <%= form_for([@activity], :remote => true) do |f| %>
     <fieldset>
       <%= f.label :title, "Activity" %><br />
       <%= f.text_field :title, :rows => 1 %><br />
     </fieldset>

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

ok lets say you want to add a new activity to a day. 好的,假设您要添加一天的新活动。

do not forget that we are using REST here so (http://old.thoughtsincomputation.com/posts/understanding-rest-in-rails-3) 不要忘记我们在这里使用REST(http://old.thoughtsincomputation.com/posts/understanding-rest-in-rails-3)

our day must have many activities and our activity belongs_to a day 我们的一天必须进行很多活动,而我们的活动属于一天

class Day < ActiveRecord::Base
  has_many :activities
end

class Activity < ActiveRecord::Base
  belongs_to :day
end

our routes should me something like 我们的路线应该像我

resources :days do
  resources :activities
end

with that routes the generated paths we have is something like 有了路线,我们拥有的生成路径就像

days_path
day_path
new_day_path

new_day_activity_path
delete_day_activity_path
edit_day_activity_path

in our day view we are in a url like localhost:3000/days/1 (DaysController, action show) 在我们的日视图中,我们位于localhost:3000 / days / 1之类的网址(DaysController,动作显示)

in wich case we can add a @activity = Activity.new and in a partial add the form below 在这种情况下,我们可以添加@activity = Activity.new,并在下面的部分添加以下表格

<%= form_for [@day, @activity] do |form_field| %>
  rest_code_goes_here
<% end %>

this form will submit in ActivityController, action :create with the day and the controller will check for validation and save it . 该表格将在ActivityController中的action:create with day提交,然后控制器将检查验证并保存。

take a look at the link is a small app i have used something like that https://github.com/leftis/tefteraki/blob/master/app/views/debts/_new_dose.haml 看看链接是一个小应用程序,我已经使用过类似的东西https://github.com/leftis/tefteraki/blob/master/app/views/debts/_new_dose.haml

Oh that actualy means that trip have many days and the resouces have more nesting something like 哦,这实际上意味着旅行有很多天,而资源有更多类似的嵌套

resources :trips
  resources :days
    resources :activities
  end
end

so when you are in local/trips/1/ you actually are in TripController, show action you cannot do it without creating a day texhnicaly you can have a form for the day in which you can use nested form for activities. 因此,当您在local / trips / 1 /中时,您实际上在TripController中,请显示动作,而无需创建一天,就无法做到这一点。您可以在当日拥有一个可将嵌套表单用于活动的表单。

the easy way is the gem of ryan bates https://github.com/ryanb/nested_form but to do that you must first change your relations from habtm to 最简单的方法是ryan bates的瑰宝https://github.com/ryanb/nested_form,但要做到这一点,您必须先将关系从habtm更改为

class Day
  has_many :activities
end

class Activity
  belongs_to :day
end

then you will add a day form inside you trip show view 然后您将在行程显示视图中添加一个日间表单

<% nested_form_for [:trip, Day.new], :remote => true do |form| %>

  <%= form.text_field :date %>

  <%= form.fields_for :activities do |activity_form| %>
    <%= activity_form.text_field :name %>
    <%= activity_form.link_to_remove "Remove this activity" %>
  <% end %>
  <p><%= form.link_to_add "Add an activity", :tasks %></p>

<% end %>

the form now makes a request to DaysController.create with params for the trip and the activities and asking to be served ajaxly 表单现在向DaysController.create发出了一个带有行程和活动参数的请求,并要求将其送达

check at gem and my app i am using all of this i hope it helps!!! 检查gem和我的应用程序,我正在使用所有这些功能,希望对您有所帮助!!!

This is what I ended up doing and it works. 这就是我最终所做的,并且有效。

In my show.html.erb for my "Trip". 在我的show.html.erb中作为“旅行”。

show.html.erb show.html.erb

<div id="activity_form">
<h2>Activities</h2>
</div> 

link to "Edit' an Activity. Notice the :remote => true which tells the Rails controller that this will be an AJAX request so to render edit.js.erb 链接到“编辑”一个活动。注意:remote => true,它告诉Rails控制器这是一个AJAX请求,以便呈现edit.js.erb

<%= link_to activity.location[0, 20], edit_day_activity_path(day, activity), :class=>"btn btn-info fixedwidthbtn", method: :get, :remote => true 

_form.html.erb This form partial is under the Activities View directory (../views/activities/_form.html.erb). _form.html.erb此表单部分位于“活动视图”目录(../views/activities/_form.html.erb)下。

<%= form_for([@day, @activity], :remote => true) do |f| %>
<fieldset>
  <%= f.label :title, "Activity" %>
  <%= f.text_field :title, :rows => 1 %> 
</fieldset>
  <div class="actions">
    <%= f.submit %>
  </div>
</form>
   <%= link_to 'Delete', [@day, @activity], method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>

edit.js.erb This is a file under the Activities view directory (../views/activities/edit.js.erb). edit.js.erb这是“活动”视图目录(../views/activities/edit.js.erb)下的文件。 Says to grab the DOM element with ID of "activity_form" and render the partial "form" 说要获取ID为“ activity_form”的DOM元素并呈现部分“ form”

$("#activity_form").html("<%= escape_javascript(render(:partial => "form"))%>");

update.js.erb I included this javascript after hitting update on the Edit form to render an updated partial of the Activities List. update.js.erb在“编辑”表单上单击“更新”以呈现“活动列表”的更新部分后,我加入了此javascript。 So that I don't have to reload the page to see an update. 这样我就不必重新加载页面即可查看更新。

$("#activities_list").html("<%= escape_javascript( render(:partial => "/trips/activities") ) %>");

routes.rb This is how I nest my routes. route.rb这就是我嵌套路线的方式。 Only doing it 1 level following best practices. 遵循最佳做法仅做1级。

resources :trips do resources :days end 资源:旅行做资源:天结束

resources :days do resources :activities end 资源:天做资源:活动结束

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM