Ruby Rails 从搜索中提取属性并使用此属性搜索另一个 table
Ruby on Rails Pluck attribute from search and search another table with this attribute
好的,在我的 Ruby on Rails 应用程序中,我正在创建一个影院应用程序。我正在尝试实现用户可以点击日期的搜索,例如今天或明天,所有在这些日期放映的电影都将被归还。
基本上是这样的:http://www.odeon.co.uk/cinemas/covent_garden/81/ 用户可以 select 不同的日期。
我会提供我的代码,然后解释我遇到的问题。
views/_search.html.erb:
<%= form_tag my_path do %>
<% date = Date.today %>
<%= hidden_field_tag :search_string, date.strftime("%F") %>
<div class="tab-content">
<%= submit_tag "What's on", class: "btn" %>
</div>
<% (1..6).each do |i| %>
<% date = Date.today + i %>
<%= hidden_field_tag :search_string, date.strftime("%F") %>
<%= submit_tag date.strftime("%a %D"), class: "btn" %>
<% end %>
<% end %>
routes.rb:
post 'films/search', to: 'films#search'
films_controller.rb:
def search
@films = Film.date_search(params[:search_string])
else if @films.empty?
flash.now[:alert] = "There are no films showing with that date - Showing all films."
@films = Film.all.order :title
end
render :action => "index"
end
film.rb:
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
self.where("id = ?", film)
end
协会 - film.rb:
has_many :showings
belongs_to :certificate
belongs_to :category
协会 - showing.rb:
belongs_to :film
has_many :bookings
belongs_to :screen
架构:
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
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
我收到以下错误:
ActiveRecord::StatementInvalid in FilmsController#search
SQLite3::SQLException: near ",": syntax error: SELECT COUNT(*) FROM "films" WHERE (id = 3,6)
我明白为什么会出现错误,但有人可以帮我解决这个问题吗?
最直接的问题是您的 date_search
方法中的以下行:
self.where("id = ?", film)
因为 film
是一个数组,SQL 术语中的正确语法应该是:
self.where("id IN (?)", film)
要处理这两种情况,即单值和数组,您需要这样:
self.where(id: film)
但是 您的 date_search
class 方法实际上应该是在 showings
上应用内部联接的作用域。这是代码:
# in your Film model
scope :date_search, ->(ss){ joins(:showings).where(showings: {show_date: ss}).group("films.id") }
看起来您是搜索方法的 where 子句想要单个记录 (id) 但它得到的是一个数组:
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
self.where("id = ?", film)
end
应该是
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
# film is an ActiveRecord relation (like an array)
self.where(id: film) # this will then run where(id IN (3, 6)), which are the values in your error in the original post
end
总而言之就是你的film =
表达式returns多于1个结果,所以where(id = ?)
永远不会运行没有错误。它必须是 IN
。
或
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).first.pluck(:film_id)
# if you add .first, then it will only return one record but that may not be what you want.
self.where("id = ?", film)
end
好的,在我的 Ruby on Rails 应用程序中,我正在创建一个影院应用程序。我正在尝试实现用户可以点击日期的搜索,例如今天或明天,所有在这些日期放映的电影都将被归还。
基本上是这样的:http://www.odeon.co.uk/cinemas/covent_garden/81/ 用户可以 select 不同的日期。
我会提供我的代码,然后解释我遇到的问题。
views/_search.html.erb:
<%= form_tag my_path do %>
<% date = Date.today %>
<%= hidden_field_tag :search_string, date.strftime("%F") %>
<div class="tab-content">
<%= submit_tag "What's on", class: "btn" %>
</div>
<% (1..6).each do |i| %>
<% date = Date.today + i %>
<%= hidden_field_tag :search_string, date.strftime("%F") %>
<%= submit_tag date.strftime("%a %D"), class: "btn" %>
<% end %>
<% end %>
routes.rb:
post 'films/search', to: 'films#search'
films_controller.rb:
def search
@films = Film.date_search(params[:search_string])
else if @films.empty?
flash.now[:alert] = "There are no films showing with that date - Showing all films."
@films = Film.all.order :title
end
render :action => "index"
end
film.rb:
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
self.where("id = ?", film)
end
协会 - film.rb:
has_many :showings
belongs_to :certificate
belongs_to :category
协会 - showing.rb:
belongs_to :film
has_many :bookings
belongs_to :screen
架构:
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
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
我收到以下错误:
ActiveRecord::StatementInvalid in FilmsController#search
SQLite3::SQLException: near ",": syntax error: SELECT COUNT(*) FROM "films" WHERE (id = 3,6)
我明白为什么会出现错误,但有人可以帮我解决这个问题吗?
最直接的问题是您的 date_search
方法中的以下行:
self.where("id = ?", film)
因为 film
是一个数组,SQL 术语中的正确语法应该是:
self.where("id IN (?)", film)
要处理这两种情况,即单值和数组,您需要这样:
self.where(id: film)
但是 您的 date_search
class 方法实际上应该是在 showings
上应用内部联接的作用域。这是代码:
# in your Film model
scope :date_search, ->(ss){ joins(:showings).where(showings: {show_date: ss}).group("films.id") }
看起来您是搜索方法的 where 子句想要单个记录 (id) 但它得到的是一个数组:
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
self.where("id = ?", film)
end
应该是
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).pluck(:film_id)
# film is an ActiveRecord relation (like an array)
self.where(id: film) # this will then run where(id IN (3, 6)), which are the values in your error in the original post
end
总而言之就是你的film =
表达式returns多于1个结果,所以where(id = ?)
永远不会运行没有错误。它必须是 IN
。
或
def self.date_search(search_string)
film = Showing.where("show_date = ?", search_string).first.pluck(:film_id)
# if you add .first, then it will only return one record but that may not be what you want.
self.where("id = ?", film)
end