根据首次下拉菜单中的选择更新第二个下拉菜单

时间:2015-02-19 20:04:15

标签: ruby-on-rails ruby drop-down-menu

我正在使用Ruby on Rails构建一个影院应用程序,目前正在开发预订系统。我想要做的是从下拉菜单中选择一部电影,然后在下拉菜单中显示该电影的放映时间,用户可以选择一个放映时间,然后可用的座位显示在下拉菜单。

我观看了这段视频:https://www.youtube.com/watch?v=GYg6s-b1XGo并查看了很多其他网站,但我想做的事情有点复杂。

好的,我的模特/ bookings.rb:

class Booking < ActiveRecord::Base
    belongs_to :user
    belongs_to :showing
    belongs_to :seat
end

模型/ showing.rb:

class Showing < ActiveRecord::Base
  belongs_to :film
  has_many :bookings
  belongs_to :screen

  def showing_times
    "#{show_date.strftime("%e %b %Y")} @ #{show_time.strftime("%H:%M")}"
  end
end

模型/ seats.rb:

class Seat < ActiveRecord::Base
    belongs_to :screen
    has_many :bookings

    def seats_available
        "#{row_letter}#{row_number}"
    end
end

这是它变得复杂的地方,我的观点/预订/ _form.html.erb:

             <%= form_for @booking do |f| %>
                <%= f.hidden_field :user_id %>
                <%= image_tag "thor_hammer.jpg",:size => "900x250" %>
                <td width="300px">

                    <br><%= f.label :film_id, 'Film:' %>
                    <br><%= f.collection_select :film_id, Film.all, :id,:title_info %>

                    <br><%= f.label :showing_id, 'Showing:' %>
                    <br><%= f.collection_select :showing_id, Showing.all, :id,:showing_times %>

                    <br><%= f.label :seat_id, 'Seat ID:' %>
                    <br><%= f.collection_select :seat_id, Seat.all, :id,:seats_available %><br>
                </td>
                <td width="300px">
                    <div class="actions">
                      <%= f.submit %>
                    </div>
                    <br>    
                    <%= render "/error_messages", :message_header => "Cannot save: ", :target => @booking %> 
                </td>
            <% end %> 

这是因为行<%= f.collection_select :film_id, Film.all, :id,:title_info %>导致错误而变得复杂的地方:

NoMethodError in Bookings#new 
undefined method `film_id' for #<Booking:0x584e6b0>

因为预订数据表没有存储电影,所以它存储了显示时间,并且它有与之相关的电影,这对于座位是相同的:用户需要能够选择显示来选择座位但是showings表与屏幕表相关联,屏幕表与座位相关联。

为了更清楚,这里是架构:

create_table "bookings", force: :cascade do |t|
  t.integer  "user_id"
  t.integer  "showing_id"
  t.integer  "seat_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "films", force: :cascade do |t|
  t.string   "title"
  t.string   "synopsis"
  t.string   "director"
  t.string   "cast1"
  t.string   "cast2"
  t.string   "cast3"
  t.date     "release_date"
  t.string   "warnings"
  t.datetime "created_at",     null: false
  t.datetime "updated_at",     null: false
  t.string   "image_url"
  t.string   "certificate_id"
  t.integer  "category_id"
  t.integer  "hours"
  t.integer  "minutes"
  t.string   "video_url"
end

create_table "screens", force: :cascade do |t|
  t.string   "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "seats", force: :cascade do |t|
  t.string   "row_letter"
  t.integer  "row_number"
  t.integer  "screen_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "showings", force: :cascade do |t|
  t.date     "show_date"
  t.time     "show_time"
  t.integer  "film_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer  "screen_id"
end

有人有任何建议吗?

1 个答案:

答案 0 :(得分:0)

您正在尝试设置film_id类实例的Booking。您是正确的,注意到film_id表中没有bookings

实现目标的最简单方法是向film_id表添加bookings,并在has_one之间创建belongs_toBooking关联}和Film

另一种实现这一目标的方法是,要求您深入了解rails,就是使用accepts_nested_attributes_for。如果你遇到第一个问题,这里有一个很好的tutorialnewer tutorial。这样您就不必创建冗余关联。

更新1

仔细观察你想要做的事情后,我意识到你并没有尝试创建一个新的资源(电影)所以请忽略我之前关于嵌套属性的评论。

你要做的事情的解决方案涉及一些有点太长的移动部件,无法给出这样的答案。但是,这里有一个摘要,可以在您尝试解决时指导您:

  • 您需要一个单独的表格才能首先选择电影
  • 根据电影选择,您可以使用ajax获取属于该电影的所有放映(为此您需要阅读ajax;您还需要了解如何通过json端点公开您的数据rails)您最终会传递用户选择的电影的ID,您将返回此查询的结果:Showing.where(film_id: <id>)
  • 在您设法获取该数据后,您需要以第二种形式填充该数据,最终只显示与该电影相关的放映。

对于您要做的事情,这似乎有点复杂。我建议的是你要么:

  • 花一些时间来弄清楚如何以不同的方式构建模型
  • 或者您不允许用户选择电影,然后在同一页面上(动态)选择放映。让他们先选择电影。选择电影后,他们会被重定向到一个页面,在那里他们可以选择放映。这对用户来说是一种更糟糕的体验,但它可以让你更好地理解rails(在这种情况下不需要ajax和javascript)。

我认为你这样做是为了更好地掌握rails,所以我希望这些信息对你有所帮助。祝你好运!