I'd like to create a search function on Rails, but I'm into it, so I'd like you to teach me.
I would like to create a search form where Rails has models called Article and Item, and there is a URL column in the item, and I can search for partial matches based on that URL.
Currently, @items=Item.where("url like%#{params[:search]}") .uniq
allows you to search by like based on the parameters (:search) entered in the form.
It's done so far, but I'd like to pull the record of the article tied to the item from here, but I can't think of a way.The article and item are linked to the item with the article_id associated with the article id.
You can use joins to search for related tables.
However, embedding parameters directly into a string can cause SQL injection, which is very dangerous.
Try binding using ? as follows:
articles=Article.joins(:items).where("items.url LIKE?", "%#{params[:search]}").uniq
Learn more about SQL injection here.
Rails Security Guide|Rails Guide
P.S.
By the way, if you understand what SQL injection is, you will be able to understand the fun of the following four-frame manga.
translation
For Rails 4.2, you can use the method sanitize_sql_like
.
This is how to use it.
class Article <ActiveRecord::Base
has_many —Items
scope:keyword_search, ->(keyword){
joins(:items).where("items.url LIKE?", "%" + sanitize_sql_like(keyword))
}
end
# controller
articles=Article.keyword_search (params[:search])
In LIKE searches, '%' or '_' have a special meaning.
You can use sanitize_sql_like to escape these strings.
Example: SQL
When the keyword '100%' is enteredSELECT...WHERE(items.url LIKE '%100\%')
First,
where("url like%#{params[:search]}")
There are many bad things about , so I'll fix it.First of all, the search string is not literal at the root, so the original code must be
where("url like'%#{params[:search]}'")
I guess so. So this is
There is a pretty serious problem, so I'll rewrite it using Arel.
search_key="%"+params[:search].gsub(/[%_]/, "\\0")
Item.where(Item.arel_table[:url].matches(search_key, "\\"))
This will eliminate the above problem.However, if Rails are out of date, #matches
may not support the second argument.In that case,
Item.where(%q!"items.url"LIKE?ESCAPE'\\'!,search_key)
muddy the tea in .You should modify the column name table because duplicate column names can result in errors if you use
joins
.
Then, which one do you want to search for?
Add the belongs_to:article
relationship to the item
.
@item=Item.where(...)
@items[0].article
See the article in
Add the has_many:items
relationship to the Article
.
Article.joins(:items).where(...).uniq
The original code #uniq
didn't make much sense, but if you don't add #uniq
, article
will overlap if there are multiple items
with the same article_id
.
Assume that has_many:items
is defined in the model as follows
class Article <ActiveRecord::Base
has_many —Items
end
class Item<ActiveRecord::Base
end
Then you can do it by using joins
articles=Article.joins(:items).where("items.url like'%#{params[:search]}}').uniq
© 2024 OneMinuteCode. All rights reserved.