I have a search bar on my navigation header where users can search for the titles of articles. This will route them to the articles/browse.html.erb page where they can further scope the results down by categories and name of authors.
I have followed this tutorial to do the navbar search. I have attempted to use Ransack to allow further filtering on the browse page. However, i'm having diffculty combining the 2 search methods with the following issues:
1) The navbar search works fine and returns the correct results, but when i filter the results further again by category name, i get EDIT 0 results ALL the results.
2) When i do the initial search on the browse page itself with the article title, ransack works. However, Ransack doesn't seem to work when i further scope the results down by category/author name. (EDIT: ransack works for filter by category with the below edit in browse.html.erb, but not for author name)
browse.html.erb
<%= search_form_for #q, url: browse_articles_path, method: :get do |f| %>
<div class="form-group">
<div class = "row">
<div class="col-md-12 col-sm-12 col-xs-12">
<%= f.search_field :title_cont, placeholder: "Find Articles", class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<div class ="row">
<div class="col-md-6 col-sm-6 col-xs-6">
<%= f.select :categories_name_cont, options_from_collection_for_select(Category.all, //EDIT change "id" to// "name", "name", #q.categories_name_eq),
{ :prompt => "Any Category" },
{ class: "form-control" } %>
</div>
<div class="col-md-6 col-sm-6 col-xs-6">
<%= f.search_field :users_name_cont, class: "form-control", placeholder: "Author" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.submit class: 'btn btn-primary btn-md' %>
</div>
<% end %>
<% if params[:search] %>
<%= render #articles %>
<% elsif params[:q] %>
<%= render #articles_morefilter %>
<% else %>
<%= render #articles %>
<% end %>
articles_controller.rb
def browse
if params[:search]
#articles = Article.search(params[:search])
#categories = Category.joins(:articles).where('articles.title LIKE ?', "%#{params[:search]}%").uniq
else
#articles = Article.published.order("cached_votes_up DESC")
#categories = Category.with_articles.order('name ASC').all
end
#q = Article.ransack(params[:q])
#articles_morefilter = #q.result.includes(:categories, :users)
end
EDIT model: article.rb
class Article < ApplicationRecord
belongs_to :user
has_many :article_categories
has_many :categories, through: :article_categories
def self.search(search)
where('title LIKE ?', "%#{search}%")
end
end
routes.rb
resources :articles do
collection do
get 'browse'
end
end
schema:
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "description"
t.bigint "user_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
end
_navigation.html.erb
<%= form_tag(browse_articles_path, :method => 'get', :id => "articles_search") do %>
<div class="form-group">
<%= text_field_tag :search, params[:search], placeholder: "Search", class: "form-control" %>
</div>
<button type="submit" class="btn btn-default">Search</button>
<% end %>
you should be able to simply search all the fields with ransack. (based on current browse.html.erb)
def browse
#q = Article.ransack(params[:q])
#articles = #q.result.includes(:categories, :users)
end
Related
Hey Guys I am getting issue, No Route Matches, though I have created both new as well as create method.
portfollios_controller.rb
class PortfolliosController < ApplicationController
def index
#portfolio_items = Portfollio.all
end
def new
#portfolio_item = Portfollio.new
end
def create
#portfolio_item = Portfollio.new(params.require(:portfollio).permit(:title, :subtitle, :body))
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfollio_path, notice: 'Your portfolio item is now live.' }
else
format.html { render :new }
end
end
end
end
routes.rb
Rails.application.routes.draw do
resources :portfollios
end
new.html.erb
<h1>Create a new Portfolio Item</h1>
<%= form_with(model: #portfolio_items, local: true) do |form| %>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div class="field">
<%= form.label :subtitle %>
<%= form.text_field :subtitle %>
</div>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Can someone help me out with the issue. I am not able to figure it out.
I figured it out. The issue is with with the file new.html.erb
I needed to change below line:-
<%= form_with(model: #portfolio_items, local: true) do |form| %>
to
<%= form_with(model: #portfolio_item, local: true) do |form| %>
It should be #portfolio_item not plural.
Hi I have a primary model, recipes with a has_many association with ingredients, which also has_many recipes, my join table is recipes_ingredients, the join table has the columns recipe_id, ingredient_id, and quantity. The quantity is just a string for how many times that ingredient will be used in that recipe.
I have a form that creates the recipe and saves it in the database at the same time it creates and saves any ingredients that are given in the form with a nested attribute... I cannot for the life of me figure out how to add the quantity for this join-table using this same form. I would appreciate any help you can afford me... thank you so much in advance.
# models/recipe.rb
class Recipe < ApplicationRecord
belongs_to :user
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
validates :name, :content, :cook_time, presence: true
def ingredients_attributes=(ingredients_hash)
ingredients_hash.each do |i, ingredients_attributes|
if ingredients_attributes[:name].present?
ingredient = Ingredient.find_or_create_by(name: ingredients_attributes[:name].capitalize!)
if !self.ingredients.include?(ingredient)
self.recipe_ingredients.build(:ingredient => ingredient)
end
end
end
end
# models/ingredient.rb
class Ingredient < ApplicationRecord
has_many :recipe_ingredients
has_many :recipe, through: :recipe_ingredients
validates :name, presence: true
end
# models/recipe_ingredient.rb
class RecipeIngredient < ApplicationRecord
belongs_to :ingredient
belongs_to :recipe
end
# form
<%= form_with(model: instruction, local: true) do |form| %>
<% if instruction.errors.any? %>
<div id="error_explanation">
<h4><%= pluralize(instruction.errors.count, "error") %> prohibited
this instruction from being saved:</h4>
<ul>
<% instruction.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container">
<div class="row">
<div class="col-sm-6">
<h3 class="text-center">Recipe</h3>
<div class="fields">
<%= form.label :name %><br>
<%= form.text_field :name, :placeholder => "Name" %><br>
<%= form.label "Instructions" %><br>
<%= form.text_area :content, :placeholder => "Recipe
Instructions" %><br>
<%= form.label :cook_time %><br>
<%= form.text_field :cook_time, :placeholder => "(ex,. 45
mins)" %><br>
<%= form.hidden_field :user_id, value: params[:user_id] %>
</div>
</div>
<div class="col-sm-6">
<h3 class="text-center">Ingredients</h3>
<div class="row">
<div class="col-sm-6 checkbox">
<%= form.collection_check_boxes(:ingredient_ids,
Ingredient.all, :id, :name) %>
</div>
<div class="col-sm-6">
<%= form.fields_for :ingredients do
|ingredient_builder| %>
<%= ingredient_builder.text_field :name %><br>
<% end %>
</div>
</div>
</div>
</div>
<div class="row justify-content-center submit-row">
<div class="fields text-center">
<%= form.submit %>
</div>
</div>
</div>[![enter image description here][1]][1]
You should use accepts accepts_nested_attributes_for
Visit for more information:
Rails has_many :through nested form
https://www.pluralsight.com/guides/ruby-ruby-on-rails/ruby-on-rails-nested-attributes
http://guides.rubyonrails.org/form_helpers.html#building-complex-forms
i need your help to create parent-child relation.
i have a problem to make the create of the child working fine.
this is the model:
class Nccheklist < ActiveRecord::Base
has_many :children, class_name: "Nccheklist", foreign_key: "parent_id"
belongs_to :parent, class_name: "Nccheklist"
def has_parent?
parent.present?
end
def has_children?
children.exists?
end
end
the controller:
def create
#nccheklist = Nccheklist.new(nccheklist_params)
if #nccheklist.save
redirect_to nccheklists_url, notice: 'Nccheklist was successfully created.'
else
render :new
end
end
and the view :
<%= form_for(#nccheklist) do |f| %>
<% if #nccheklist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#nccheklist.errors.count, "error") %> prohibited this nccheklist from being saved:</h2>
<ul>
<% #nccheklist.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div>
<%= f.collection_select(:parent_id, #rootcat, :id, :name) %>
</div>
<br/><br/>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
when i submit the form, parent_id always equal null on database !
can someone help me please.
thanks.
add the following to the class definition
accepts_nested_attributes_for :children, allow_destroy: true
i need some help to put a search field on my view.
I got a families table, and each family got 0-n books. I want to make a search that only families of a specific book are show.
Right now i am using ransack for some other simple searches:
Controler:
class FamiliesController < ApplicationController
def index
#search = Family.search(params[:q])
#families = #search.result
respond_to do |format|
format.html # index.html.erb
format.json { render json: #families }
end
end
model:
class Family < ActiveRecord::Base
has_many :names
has_and_belongs_to_many :books, :join_table => "books_families"
has_and_belongs_to_many :races, :join_table => "families_races"
attr_accessible :descr, :nome, :book_ids, :race_ids
validates :nome, uniqueness: true, presence: true
end
View:
<fieldset>
<legend>Filter for families</legend>
<%= search_form_for #search do |f| %>
<div class="field">
<%= f.label :nome, "Name: " %><br />
<%= f.text_field :nome_cont, :class => "search-field"%>
</div>
<div class="actions">
<%= f.submit "Search" %>
</div>
<% end %>
</fieldset>
<table>
<tr>
<th><%= sort_link(#search, :nome, "Name") %></th>
<th>Books</th>
<th>Descr</th>
</tr>
(...)
<td>
<ol type="disc">
<% family.books.each do |book| %>
<li> <%= book.nome %> </li>
<% end %>
</ol>
</td>
(...)
What should i do?
I'm not familiar with ransack, but your query should be achievable with SQL. I don't know your all of your table/field names, but something like this should work.
#families = Family.where("families.id IN(SELECT books_families.family_id FROM
books_families WHERE books_families.book_id IN(
SELECT books.id FROM books WHERE books.title LIKE(?)))",
"%" + params[:q] + "%")
Finally got the solution. its a simple 2 line thing:
<div class="field">
<%= f.label :books_id_eq, "Livro:" %><br />
<%= f.collection_select :books_id_eq, Book.order(:nome), :id, :nome, :include_blank => "Todos" %>
</div>
I'm trying to create the form to create an event. Events belong_to a creator (of class user), and the form includes fields_for the creator.
Largely the form is working - it renders everything else properly, and the create action processes it properly when the fields_for #event.creator section is commented out. The fields_for tag is rendering event[user] tags instead of event[creator], though, and i can't figure out why. Ideas? Here are the relevant excerpts.
(in views/events/new.html.erb)
<%= form_for #event do |form| %>
<%= render :partial => '/events/form', :object => form %>
<%= form.submit 'Go!' %>
<% end %>
(in events/_form.html.erb)
...
<% if !signed_in? %>
To create your event, please provide an email address and create a password. <br />
<%= form.fields_for #event.creator do |uf| %>
<div class="email_field">
<%= uf.label :email %>
<%= uf.text_field :email, :type => "email" %>
</div>
...
<% end %>
<% end %>
(controllers/events_controller.rb)
def new
#event = Event.new
if !signed_in?
#event.build_creator
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #event }
end
end
(models/event.rb)
belongs_to :creator, :class_name => "User"
accepts_nested_attributes_for :creator
Largely this works, but the form elements render as
<div class="email_field">
<label for="event_user_email">Email</label>
<input id="event_user_email" name="event[user][email]" size="30" type="email" />
</div>
<div class="password_field">
<label for="event_user_password">Password</label>
<input id="event_user_password" name="event[user][password]" size="30" type="password" />
</div>
...
the issue here is event_user and event[user] instead of event_creator and event[creator]; when i submit the form i get an error that event doesn't have a User field.
<%= form.fields_for :creator, #event.creator do |uf| %>