如何以多种形式访问多个模型 [英] How to access multiple models in multiple forms

查看:33
本文介绍了如何以多种形式访问多个模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我要感谢 SO 的每一个人.在过去的几天里,我从你们那里得到了很多帮助,非常感谢!

我手上还有一个问题:

背景/目标:
我有一个游览、日间和预订模式.在我的游览控制器中,我可以创建游览并手动输入游览可用的天数.然后我想访问每个旅游预订页面 (tours/1/reservation/new) 并显示旅游信息以及旅游指定日期.

我的问题是:
1) 我需要在我的预订控制器和视图中输入什么才能访问选择标签中的每个旅行指定日期?

2) 是否有 Rails 方法可以将输入的一周中的天数转换为显示指定日期及其日期的动态形式?
例如:巡演 #1 每周一和周二可用(这些是在我创建巡演时手动输入的天数).我怎样才能把那些日子变成一个动态的形式,其中 Rails 显示每个月的每个星期一和星期二的日期?(我可能会为此发布另一个问题,只是想知道,因为它有点相关.)

深入的解释总是值得赞赏的,因为我有点无能为力.:(再次感谢您!

更新:
每次旅行的天数不会显示在预订页面上,如果它们在 form_helper 中,或者甚至是像我将引导程序下拉菜单类应用到周围元素这样简单的东西.

这有效:(显示天数)

 
    <% @tour.days.all.each 做 |day|%><li><%= day.name %><%结束%>

这不会:

 

也不是这个:

 <% @tour.days.each do |day|%><%= f.fields_for :day do |builder|%><%= builder.label :id, '可用天数:'%><br/><%= builder.select :id, options_from_collection_for_select(day, 'id', 'name') %><%结束%><%结束%>

我完全被难住了.

模型:

课程导览拉姆达 { |a|a[:name].空白?}, :allow_destroy =>真的结尾班级预订拉姆达 { |a|a[:name].空白?}, :allow_destroy =>真的结尾上课日ActiveRecord::Base归属地:游览has_many :reservations, 依赖: :destroyaccepts_nested_attributes_for :reservations, allow_destroy: true, :reject_if =>拉姆达 { |a|a[:name].空白?}, :allow_destroy =>真的结尾

迁移:
类 CreateTours <ActiveRecord::迁移定义改变create_table :tours do |t|t.string :namet.integer :amount

 t.timestamps结尾结尾结尾类 CreateDays 

观看次数:
游览

<div class="row"><div class="col-md-12"><h2>添加新游览</h2><%= bootstrap_form_for(@tour) 做 |f|%><%= f.text_field :name %><%= f.fields_for :days do |builder|%><%= builder.label :name, '游览天数:' %><%= builder.text_field :name, label: 'Days of Tour:' %><%= builder.check_box :_destroy %><%= builder.label :_destroy, '删除日期' %><%结束%><%= f.text_field :amount %><%= f.text_field :time %><%= f.submit '添加此游览' %><%结束%>

预订

<div class="容器"><div class="row"><div class="col-md-9"><h2><%=@tour.name %>

<div class="col-md-3"><p><%=@tour.amount %></p><%= bootstrap_form_for([:tour, @reservation], html: { class: 'form-horizo​​ntal', id: 'payment-form'}) do |f|%><%= f.alert_message '请修正以下错误:' %><%= f.select :passengers, options_for_select( (1..10).map { |n| n %1 == 0 ? n.to_i : n } ) %><%= f.fields_for :days do |builder|%><%= builder.label :name, '可用天数:'%><br/><%= builder.text_field :name %><%结束%><fieldset class="credit_card"><span class="payment-errors"></span></fieldset><div class="control-group"><%= label_tag :card_number, '信用卡号:', class: 'control-label' %><div class="控件"><%= text_field_tag :card_number, nil, name: nil, class: 'span3', data: {stripe: 'number'} %>

<div class="control-group"><%= label_tag :security_code, 'Security code:', class: 'control-label' %><div class="控件"><%= text_field_tag :security_code, nil, name: nil, class: 'span3', data: {stripe: 'cvc'} %>

<div class="control-group"><%= label_tag :exp_date, 'Expiration:', class: 'control-label' %><div class="控件"><%= select_month(Date.today, {add_month_numbers: true}, class: 'span2', data: {stripe: 'exp-month'}) %><%= select_year(Date.today.year, {start_year: Date.today.year, end_year: Date.today.year + 4}, class: 'span1', data: {stripe: 'exp-year'})%>

<fieldset class="actions control-group"><div class="控件"><%= f.submit '注册' %>

</fieldset><%结束%>

控制器:

class ReservationsController <应用控制器定义索引结尾定义新@reservation = Reservation.new@tour = Tour.find(params[:tour_id])结尾定义创建@tour = Tour.find(params[:tour_id])如果@reservation.update_attribute(:t_shirt, params[:t_shirt]) == true ||@reservation.update_attribute(:hat, params[:hat]) == true@tour.amount = @tour.amount + 15别的@tour.amount = @tour.amount结尾@reservation = Reservation.new(reservation_params)如果@reservation.saveStripe.api_key = ENV["STRIPE_SECRET_KEY"]Stripe::Charge.create(:金额=>@tour.amount, # 美分,再次:货币=>美元",:卡=>参数[:stripeToken])flash[:success] = "您的预订已为 #{@reservation.passengers} 人预订.请保存此信息."redirect_to new_tour_reservation_path(@tour)别的呈现新"结尾结尾私人的定义保留参数params.require(:reservation).permit(:date, :passengers, days_attributes: [:id, :name, :_destroy])

结束结束

class ToursController <应用控制器定义索引@tours = Tour.all结尾定义新@tour = Tour.new7.times { @tour.days.build }结尾定义创建@tour = Tour.new(tours_params)如果@tour.saveflash[:success] = "Tour #{@tour.name} 已成功添加."redirect_to new_tour_path别的flash[:error] = "巡演#{@tour.name} 没有成功保存.请重试"呈现新"结尾结尾高清秀@tour = Tour.find_by(id: params[:id])@reservation = Reservation.new结尾定义编辑@tour = Tour.find_by(id: params[:id])结尾定义更新@tour = Tour.find_by(id: params[:id])如果@tour.update_attributes(tours_params)flash[:success] = "#{@tour.name} 已成功更新."重定向到 tours_path别的flash[:error] = "#{@tour.name} 尚未更新.请重试."渲染编辑"结尾结尾定义删除@tour = Tour.find_by(id: params[:id])结尾销毁@tour = Tour.find_by(id: params[:id])如果@tour.destroyflash[:success] = "#{@tour.name} 已成功删除."重定向到 tours_path别的flash[:error] = "#{@tour.name} 尚未删除.请重试."渲染编辑"结尾结尾私人的def tours_paramsparams.require(:tour).permit(:name, :amount, days_attributes: [:id, :name, :_destroy])结尾结尾

路线:

Rails.application.routes.draw 做资源:旅游做资源:预订结尾结尾

解决方案

@tour.days 是一个数组,我相信.您需要的是单个实例.

看看这是否有效:

<% @tour.days.each do |day|%><%= f.fields_for :day do |builder|%><%= builder.label :id, '可用天数:'%><br/><%= builder.select :id, options_from_collection_for_select(day, 'id', 'name') %><%结束%><%结束%>

如果您在 API 中查找 options_from_collection_for_select,您会注意到它们这个例子:

options_from_collection_for_select(@people, 'id', 'name')

@people 是单个对象.不是数组.其中 @tour.days 是一个数组

First, I want to thank everyone at SO. I've been getting a lot of help from you guys the last couple days and it's much appreciated!

I have another problem on my hands:

Background/Goal:
I have a Tour, Day, and Reservation model. In my Tour controller, I can create a tour and manually enter in days that the tour is available on. I then want to access each tours reservation page (tours/1/reservation/new) and display the tour information along with the tour designated days.

My question are:
1) What do I need to put in my reservations controller and view in order for me to access each tours designated days in a select tag?

2) Is there a Rails way to turn the inputted days of the week into a dynamic form where it displays the designated day and their dates?
For an example: Tour #1 is available on Mondays and Tuesdays (every week) (these are manually entered in days when I create the tour). How can I turn those days into a dynamic form where Rails displays the date of every Monday and Tuesday in each month? (I will probably post another question for this, just wondering since it's somewhat related.)

Deep explanations are always appreciated, as I'm a bit clueless. :( Thank you again!

UPDATE:
The days of each tour are NOT being displayed on the reservations page IF they're in a form_helper or even something as simple as me applying a bootstrap dropdown-menu class to the surrounding element.

This works: (shows days)

   <ul>
      <% @tour.days.all.each do |day| %>
        <li>
          <%= day.name %>
        </li>
      <% end %>
    </ul>

This DOES NOT:

   <ul class='dropdown-menu'>
      <% @tour.days.all.each do |day| %>
        <li>
          <%= day.name %>
        </li>
      <% end %>
    </ul>

NOR this:

 <% @tour.days.each do |day| %>
     <%= f.fields_for :day do |builder| %>
       <%= builder.label :id, 'Days available:' %><br />
       <%= builder.select :id, options_from_collection_for_select(day, 'id', 'name') %>
    <% end %>
  <% end %>

I'm completely stumped.

Models:

class Tour < ActiveRecord::Base
  has_many :days, dependent: :destroy
  has_many :reservations
  accepts_nested_attributes_for :days, allow_destroy: true, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end


class Reservation < ActiveRecord::Base
  belongs_to :tour
  belongs_to :day
  accepts_nested_attributes_for :days, allow_destroy: true, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end


class Day < ActiveRecord::Base
  belongs_to :tour
  has_many :reservations, dependent: :destroy
  accepts_nested_attributes_for :reservations, allow_destroy: true, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end

Migrations:
class CreateTours < ActiveRecord::Migration def change create_table :tours do |t| t.string :name t.integer :amount

      t.timestamps
    end
  end
end


class CreateDays < ActiveRecord::Migration
  def change
    create_table :days do |t|
      t.string :name
      t.integer :tour_id

      t.timestamps
    end
  end
end


class CreateReservations < ActiveRecord::Migration
  def change
    create_table :reservations do |t|
      t.integer :passengers

      t.integer :tour_id
      t.integer :day_id

      t.timestamps
    end
  end
end

Views:
TOUR

<div class="container">
  <div class="row">
    <div class="col-md-12">
      <h2>Add a new tour</h2>
      <%= bootstrap_form_for(@tour) do |f| %>
        <%= f.text_field :name %>
        <%= f.fields_for :days do |builder| %>
            <%= builder.label :name, 'Days of Tour:' %>
            <%= builder.text_field :name, label: 'Days of Tour:' %>
            <%= builder.check_box :_destroy %>
            <%= builder.label :_destroy, 'Remove day' %>
        <% end %>
        <%= f.text_field :amount %>
        <%= f.text_field :time %>
        <%= f.submit 'Add this tour' %>
      <% end %>
    </div>
  </div>
</div>

RESERVATION

</script>
<div class="container">
  <div class="row">
    <div class="col-md-9">
      <h2>
        <%= @tour.name %>
      </h2>
    </div>
    <div class="col-md-3">
      <p>
        <%= @tour.amount %>
      </p>
      <%= bootstrap_form_for([:tour, @reservation], html: { class: 'form-horizontal', id: 'payment-form'}) do |f| %>
        <%= f.alert_message 'Please fix the errors below:' %>
        <%= f.select :passengers, options_for_select( (1..10).map { |n| n %1 == 0 ? n.to_i : n } ) %>
        <%= f.fields_for :days do |builder| %>
          <%= builder.label :name, 'Days available:' %><br />
          <%= builder.text_field :name %>
        <% end %>
        <fieldset class="credit_card">
          <span class="payment-errors"></span>
        </fieldset>
        <div class="control-group">
          <%= label_tag :card_number, 'Credit card number:', class: 'control-label' %>
          <div class="controls">
            <%= text_field_tag :card_number, nil, name: nil, class: 'span3', data: {stripe: 'number'} %>
          </div>
        </div>
        <div class="control-group">
          <%= label_tag :security_code, 'Security code:', class: 'control-label' %>
          <div class="controls">
            <%= text_field_tag :security_code, nil, name: nil, class: 'span3', data: {stripe: 'cvc'} %>
          </div>
        </div>
        <div class="control-group">
          <%= label_tag :exp_date, 'Expiration:', class: 'control-label' %>
          <div class="controls">
            <%= select_month(Date.today, {add_month_numbers: true},  class: 'span2', data: {stripe: 'exp-month'}) %>
            <%= select_year(Date.today.year, {start_year: Date.today.year, end_year: Date.today.year + 4}, class: 'span1', data: {stripe: 'exp-year'}) %>
          </div>
        </div>
        <fieldset class="actions control-group">
          <div class="controls">
            <%= f.submit 'Sign up' %>
          </div>
        </fieldset>
      <% end %>
    </div>
  </div>
</div>

Controllers:

class ReservationsController < ApplicationController

  def index
  end

  def new
    @reservation = Reservation.new
    @tour = Tour.find(params[:tour_id])
  end

  def create
    @tour = Tour.find(params[:tour_id])

    if @reservation.update_attribute(:t_shirt, params[:t_shirt]) == true || @reservation.update_attribute(:hat, params[:hat]) == true
       @tour.amount = @tour.amount + 15
    else
       @tour.amount = @tour.amount
    end

    @reservation = Reservation.new(reservation_params)

    if @reservation.save
      Stripe.api_key = ENV["STRIPE_SECRET_KEY"]
      Stripe::Charge.create(
        :amount => @tour.amount, # amount in cents, again
        :currency => "usd",
        :card => params[:stripeToken]
      )
      flash[:success] = "Your reservation has been booked for #{@reservation.passengers} person(s). Please save this info."
      redirect_to new_tour_reservation_path(@tour)
    else
      render 'new'
    end
  end

  private

  def reservation_params
    params.require(:reservation).permit(:date, :passengers, days_attributes: [:id, :name, :_destroy])

end end

class ToursController < ApplicationController
  def index
    @tours = Tour.all
  end

  def new
    @tour = Tour.new
    7.times { @tour.days.build }
  end

  def create
    @tour = Tour.new(tours_params)
    if @tour.save
      flash[:success] = "Tour #{@tour.name} has been successfully added."
      redirect_to new_tour_path
    else
      flash[:error] = "The tour #{@tour.name} was not successfully saved. Please try again"
      render 'new'
    end
  end

  def show
    @tour = Tour.find_by(id: params[:id])
    @reservation = Reservation.new
  end

  def edit
    @tour = Tour.find_by(id: params[:id])
  end

  def update
    @tour = Tour.find_by(id: params[:id])
    if @tour.update_attributes(tours_params)
      flash[:success] = "#{@tour.name} has been successfully updated."
      redirect_to tours_path
    else
      flash[:error] = "#{@tour.name} has not been updated. Please try again."
      render 'edit'
    end
  end

  def delete
    @tour = Tour.find_by(id: params[:id])
  end

  def destroy
    @tour = Tour.find_by(id: params[:id])
    if @tour.destroy
      flash[:success] = "The #{@tour.name} has been successfully deleted."
      redirect_to tours_path
    else
      flash[:error] = "The #{@tour.name} has not been deleted. Please try again."
      render 'edit'
    end
  end

  private

  def tours_params
    params.require(:tour).permit(:name, :amount, days_attributes: [:id, :name, :_destroy])
  end
end

Routes:

Rails.application.routes.draw do
  resources :tours do
    resources :reservations
  end
end

解决方案

@tour.days is an array, I believe. What you need is a single instance.

see if this works:

<% @tour.days.each do |day| %>
   <%= f.fields_for :day do |builder| %>
   <%= builder.label :id, 'Days available:' %><br />
   <%= builder.select :id, options_from_collection_for_select(day, 'id', 'name') %>
 <% end %>
<% end %>

if you look up options_from_collection_for_select in the API, you'll notice they this example:

options_from_collection_for_select(@people, 'id', 'name')

@people is a single object. not an array. where as @tour.days is an array

这篇关于如何以多种形式访问多个模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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