I'm trying to paginate multiple tables with the Kaminari Gem. I've tried to do this by generating an array in my application controller, like so:
#paginate = %w(errors messages subscribers).page(params[:page]).per(15)
I've then taken #paginate and used it in one of my partials than renders the tables, like so:
<%= paginate #paginate %>
But I keep receiving a:
NoMethodError in Admin::ApplicationController#index
undefined method `page' for ["errors", "messages", "subscribers"]:Array
Here is the code that I've got:
Application_Controller.rb
class Admin::ApplicationController < InheritedResources::Base
protect_from_forgery
include ResourcesHelper
layout "admin"
#Setup
before_filter :set_resource_variable
before_filter :set_pagination_variable, only: :index
#Authentication
skip_before_filter :authenticate_user!
before_filter :authenticate_admin!
#Authorization
skip_before_filter :check_authentication
#Index
#Custom Index For Application/Index (no inheritance)
def index
#users = User.all
#attributes = %w(messages subscribers)
#paginate = %w(errors messages subscribers).page(params[:page]).per(15)
end
#Create
def create
create! { collection_path }
end
#Update
def update
update! { collection_path }
end
private
#Set Model Variable
def set_resource_variable
#resource = self.resource_class
#model = "#{#resource}".downcase.to_sym
end
#Pagination
def set_pagination_variable
#params[:page] ||= "1"
end
#Strong Params
def permitted_params
attributes = attributes(#resource) + %w(user_id admin_id) + [image_pages_attributes: [:caption, image_attributes: [:image]]]
params.permit(#model => attributes)
end
end
_table.html.erb
<h2><%= model %></h2>
<% unless collection.blank? %>
<table class="sort">
<thead>
<tr>
<% model.attribute_names.each do |attr| %>
<th><%= model.human_attribute_name(attr) %></th>
<% end %>
<th colspan="2"> </th>
<% if model.name == "Error" %><th> </th><% end %>
</tr>
</thead>
<tbody>
<%= render partial: "admin/resources/table/row", collection: collection, as: :resource, locals: {model: model} %>
</tbody>
</table>
_row.html.erb
<tr data-link="<%= polymorphic_path([:admin, resource]) %>">
<% model.attribute_names.each do |attr| %>
<td><%= resource.send(attr) %></td>
<% end %>
<% if model.name == "Error" %>
<td><%= link_to "Read", admin_error_read_path(resource.id), method: :put, remote: :true, class: "read" %></td>
<% end %>
<td><%= link_to "Edit", edit_polymorphic_path([:admin, resource]) %></td>
<td><%= link_to "Delete", polymorphic_path([:admin, resource]), method: :delete, data: {confirm: "Are you sure?"} %></td>
If you need anything else, let me know and I'll put it up.
Thank you!!
You're not setting "page" properly. It should always be like this:
paginate(:page => params[:page], :per_page => 15)
So in your example
#paginate = %w(errors messages subscribers).page(params[:page]).per(15)
What you really want is:
#paginate = %w(errors messages subscribers).paginate(:page => params[:page], :per_page => 15)
Related
I'm trying to add a search bar for a database website I created, I found a tutorial and I "think" I did it correct.
When I do a search, such as "Judy Zhang", nothing shows up, even though it is in the database
my vendor.rb/concerns/models/app file
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(contact_name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
I believe I didn't do the coding right. Very new to ruby on rails. What did I do wrong here?
code for index.html.erb/vendors/views/layouts/app
<body>
<div class = "head">
<h1>Vendors </h1>
<div class = "image1" >
<img src= "http://dx.deucex.com/i/logo.png" >
</div>
</div>
</body>
<table>
<tr>
<%= button_to "New Vendor", new_vendor_path, :method => "get" %>
<%= button_to "Inventory", inventories_path, :method => "get" %>
<%= form_tag vendors_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</tr>
</table>
<table>
<tr>
<th>Company</th>
<th>Contact Name</th>
<th>Phone</th>
<th>Email</th>
</tr>
<% for vendor in #vendors %>
<tr>
<td><%= vendor.company %></td>
<td><%= vendor.contact_name %></td>
<td><%= vendor.phone %></td>
<td><%= vendor.email %></td>
<body>
<div class = "button1" >
<td><%= button_to "Show", vendor_path(vendor), :method => "get" %></td>
</div>
</body>
<td><%= button_to "Edit", edit_vendor_path(vendor), :method => "get" %></td>
<div class = "button3">
<td><%= button_to 'Delete',
vendor_path(vendor),
method: :delete,
data: { confirm: 'Are you sure?'} %></td>
</div>
</tr>
<% end %>
</table>
code for my VendorsController.rb/concerns/controller/app
class VendorsController < ApplicationController
def index
#vendors = Vendor.search(params[:search])
end
def show
#vendor = Vendor.find(params[:id])
end
def new
#vendor = Vendor.new
end
def create
#vendor = Vendor.new(vendor_params)
if #vendor.save
redirect_to #vendor
else
render 'new'
end
end
def edit
#vendor = Vendor.find(params[:id])
end
def update
#vendor = Vendor.find(params[:id])
if #vendor.update (vendor_params)
redirect_to #vendor
else
render 'edit'
end
end
def destroy
#vendor = Vendor.find(params[:id])
#vendor.destroy
redirect_to vendors_path
end
end
private
def vendor_params
params.require(:vendor).permit(:company, :contact_name, :phone, :email, :moq, :cost_per_item, :payment_method, :terms, :turnover, :returns, :notes)
end
Try changing the code in Vendor to
class Vendor < ApplicationRecord
has_many :fotos
def self.search(search)
if search
Vendor.where('lower(name) LIKE ?', "'%#{search.downcase}%'")
else
Vendor.all
end
end
end
My search bar isn't showing up
You should change the following
<% form_tag vendors_path, :method => 'get' do %>
to
<%= form_tag vendors_path, :method => 'get' do %>
# Notice that <%= %> evaluates and prints the output
on my e-store website when I try to checkout my cart, I'm getting
undefined method `items' for nil:NilClass.
Although on the error page
I know that my cart is there... but when I call it, it gives me nil
Cart Model
class Cart
attr_reader :items
def self.build_from_hash hash
items = if hash["cart"] then
hash["cart"]["items"].map do |item_data|
CartItem.new item_data["product_id"], item_data["quantity"]
end
else
[]
end
new items
end
def initialize items = []
#items = items
end
def add_item product_id
item = #items.find { |item| item.product_id == product_id }
if item
item.increment
else
#items << CartItem.new(product_id)
end
end
def empty?
#items.empty?
end
def count
#items.length
end
def serialize
items = #items.map do |item|
{
"product_id" => item.product_id,
"quantity" => item.quantity
}
end
{
"items" => items
}
end
def total_price
#items.inject(0) { |sum, item| sum + item.total_price }
end
end
Application Controller
def initialize_cart
#cart = Cart.build_from_hash session
end
Cart Controller
class CartsController < ApplicationController
before_filter :initialize_cart
def add
#cart.add_item params[:id]
session["cart"] = #cart.serialize
product = Product.find params[:id]
redirect_to :back, notice: "Added #{product.name} to cart."
end
def show
end
def checkout
#order_form = OrderForm.new user: User.new
end
end
Order Controller
class OrdersController
def create
#order_form = OrderForm.new(
user: User.new(order_params[:user]),
cart: #cart
)
if #order_form.save
redirect_to '/', notice: "Thank you for placing your order."
#cart.empty?
else
render 'carts/checkout'
end
end
Checkout View
<div class="container-checkout">
<p class="text-title"> You are checking out the following: </p>
<table class="table table-striped">
<thead class="name-table">
<tr>
<td> Image </td>
<td> Name </td>
<td> Category</td>
<td> Size </td>
<td> Item Price </td>
</tr>
</thead>
<tbody>
<% #cart.items.each do |item| %>
<tr>
<td><img src="<%= item.product.image %>" width="50px"></td>
<td><%= item.product.name.capitalize %></td>
<td><%= item.product.category.name %></td>
<td><%= item.product.size %></td>
<td class="price-item"><%= number_to_currency item.total_price %>
</td>
<% end %>
</tr>
<tr class="total-price total-price-checkout">
<td class="name-table">Total Price</td>
<td class="price-item"><%= number_to_currency #cart.total_price %></td>
</tr>
</tbody>
</table>
</div>
<div class="details-user-form">
<%= form_for #order_form, url: orders_path do |f|%>
<% f.fields_for :user, #order_form.user do |u| %>
<p class="text-title">Fill the form with your details</p>
<p><%= render "orders/errors" %></p>
<p><%= u.text_field :name, placeholder: "Name" %></p>
<p><%= u.text_field :email, placeholder: "Email" %></p>
<p><%= u.text_field :address, placeholder: "Address" %></p>
<p><%= u.text_field :postal_code, placeholder: "Postal code" %></p>
<p><%= u.text_field :city, placeholder: "City" %></p>
<p><%= u.text_field :country, placeholder: "Country" %></p>
<%= f.submit "Place order", class: "order-btn"%><br>
<% end %>
<% end %>
</div>
Any idea of why is it doing so? Also because, it was working before.. I don't know why it stopped.
I think the problem may be that the #cart variable isn't being set in the OrdersController. Setting the variable in CartsController doesn't make it available globally, as it would only be scoped to the controller that created it, in your case the CartsController.
Also, I see that your Cart model is more of a virtual model than an ActiveRecord model, is that the behaviour you were looking for as I believe ActiveRecord already has a lot of the methods you're recreating there.
I'm not totally sure but I think these may be the issues.
UPDATE
I think I found your error.
In your OrdersController you should have a
before_action :initialize_cart
That seems to be coming from your ApplicationController
If you check your checkout method in your CartController, you will see that you did not set #cart. So when you hit the checkout view, it comes to look for the value or #cart in this method. Setting it there, like the code below should clear your error.
def checkout
#order_form = OrderForm.new user: User.new
#cart = # cart object
end
This is the error I get.
This is my model code.
class Subject < ActiveRecord::Base
has_many :pages
validates :name,
:presence => true,
:length => { :maximum => 255 }
scope :visible, lambda { where(:visible => true) }
scope :invisible, lambda { where(:visible => false) }
scope :sorted, lambda { order("subjects.position ASC")}
scope :newest_first, lambda { order("subject.created_at DESC") }
scope :search, lambda { |query|
where(["name LIKE ?", "%#{query}%"])
}
end
I noticed that it's saying something about my create action. So here's that:
class SubjectsController < ApplicationController
layout "admin"
def index
#subjects = Subject.sorted
end
def show
#subject = Subject.find(params[:id])
end
def new
#subject = Subject.new({:name => 'Default'})
#subject_count = Subject.count + 1
end
def create
# Instantiate a new object using form parameters
#subject = Subject.new(subject_params)
# Save the object
if #subject.save
# If save succeeds, redirect to the index
flash[:notice] = "The subject was created successfully."
redirect_to(:action => 'index')
else
#subject_count = Subject.count + 1
render(new)
end
end
def edit
#subject = Subject.find(params[:id])
#subject_count = Subject.count
end
def update
# Find an existing object using form parameters
#subject = Subject.find(params[:id])
# Update the object
if #subject.update_attributes(subject_params)
# If save succeeds, redirect to the show
flash[:notice] = "The subject was updated successfully."
redirect_to(:action => 'show', :id => #subject.id)
else
# If update fails, redisplay the form so user can fix problem.
#subject_count = Subject.count
render('edit')
end
end
def delete
#subject = Subject.find(params[:id])
end
def destroy
subject = Subject.find(params[:id]).destroy
flash[:notice] = "The subject '#{subject.name}' was deleted successfully."
redirect_to(:action => 'index')
end
private
def subject_params
# same as using "params[:subject]", except that it:
# -raises an error if :subject is not present
# -allows listed attributes to be mass-assigned
params.require(:subject).permit(:name, :position, :visible)
end
end
If I take the validations off it works, but then I can create the subject without a name. I noticed that if I add a subject the number in the paranthesis '3' moves up. I wonder if it has something to do with the select form. Here's the form:
<%= error_messages_for(#subject) %>
<table summary="Subject form fields" class="table table-hover">
<tr>
<th><%= f.label(:name, "Name") %></th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th><%= f.label(:position) %></th>
<td><%= f.select(:position, 1..#subject_count) %></td>
</tr>
<tr>
<th><%= f.label(:visible) %></th>
<td><%= f.check_box(:visible) %></td>
</tr>
</table>
Update: I'm adding the index view per request.
<% #page_title = 'Subjects' %>
<div class="subjects show">
<h2>Subjects</h2>
<%= link_to("Add New Subject", {:action => 'new'}, :class => 'action new btn btn-default') %>
<table class="listing table table-hover" summary="Subject list">
<tr class="header">
<th>Position</th>
<th>Subject</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #subjects.each do |subject| %>
<tr>
<td><%= subject.position %></td>
<td><%= subject.name %></td>
<td class="center"><%= subject.visible ? 'Yes' : 'No' %></td>
<td class="center"><%= subject.pages.size %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => subject.id}, :class => 'action edit') %>
<%= link_to("Delete", {:action => 'delete', :id => subject.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
due to a syntax error for the partial on the else part of create action, active model was throwing an exception(http://apidock.com/rails/v3.2.1/ActionView/PartialRenderer/partial_path)
def create
#few lines escaped....
else
#subject_count = Subject.count + 1
render(new) # <-- Error
end
It should be either render :new or render 'new' as mentioned by Nobilik. your method should look like:
def create
#few lines escaped....
else
#subject_count = Subject.count + 1
render :new # for best practice
end
I'm working through the rails intro guide but using 'stocks' instead of 'articles' and 'time_detlas' instead of 'comments' my issue is that it seems to be saving time_deltas correctly, I think I checked that correctly but the show of the stock just adds an extra blank row to the table of time_deltas no numbers show. Any suggestions why?
Stocks controller:
class StocksController < ApplicationController
def new
#stock = Stock.new
end
def index
#stocks = Stock.all
end
def create
# XXX Add columns for delta and current standing when we get there
# they can intiate to nil
#stock = Stock.new(stock_params)
if #stock.save
redirect_to #stock
else
render 'new'
end
end
def show
#stock = find_stock
#time_delta = #stock.time_deltas.build
end
def edit
#stock = find_stock
end
def update
#stock = find_stock
if #stock.update(stock_params)
redirect_to #stock
else
render 'edit'
end
end
def destroy
#stock = find_stock
#stock.destroy
redirect_to stocks_path
end
private
def stock_params
params.require(:stock).permit(:name, :hashtag)
end
def find_stock
return Stock.find(params[:id])
end
end
Time Delta Controller
class TimeDeltasController < ApplicationController
def create
#stock = Stock.find(params[:stock_id])
#time_delta = #stock.time_deltas.create(time_delta_params)
redirect_to stock_path(#stock)
end
private
def time_delta_params
params.require(:time_delta).permit(:start, :length)
end
end
Show for the stock
<h1> Stock </h1>
<table>
<tr>
<th>Stock</th>
<th>Hashtag</th>
</tr>
<tr>
<td><%= #stock.name %></td>
<td><%= #stock.hashtag %></td>
</tr>
</table>
<h3>TimeDeltas: </h2>
<table>
<tr>
<th>Start</th>
<th>Length</th>
</tr>
<% #stock.time_deltas.each do |time_delta| %>
<tr>
<td><%= #time_delta.start %></td>
<td><%= #time_delta.length %></td>
</tr>
<% end %>
</table>
<h3>Add a TimeDelta:</h2>
<%= form_for([#stock, #stock.time_deltas.build]) do |f| %>
<p>
<%= f.label :start %><br>
<%= f.text_field :start %>
</p>
<p>
<%= f.label :length %><br>
<%= f.text_field :length %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', stocks_path%>
<%= link_to 'Edit', edit_stock_path(#stock)%>
Any help is appreciated, thank you!
just remove # from time_delta
<% #stock.time_deltas.each do |time_delta| %>
<tr>
<td><%= time_delta.start %></td>
<td><%= time_delta.length %></td>
</tr>
<% end %>
up
You need # only to be able to share this var with your view. Eg: If you add this to your show action: #time_deltas = TimeDelta.all
you can show time_deltas in your view.
like:
<% #time_deltas.each do |td|%>
<%= td.start%>
<% end %>
I'm fairly new to Ruby on Rails, making a directory type of website as a personal project to learn.
In my app, I implemented Geocoder search so the user can search for places/locations near them, the search worked perfect. But then when I added tabbed menus to categorize what type of places are available it broke the search.
I think I know why it's broken but not sure how to fix it. The tabs are showing the #schools, #restaurants, and #businesses variables, how can I get the tabs to show the search results and not those variables? Those variables should only show up when there is no search executed, but they also show up when the search is executed.
Here's my code:
Places Controller:
class PlacesController < ApplicationController
before_filter :authenticate_user!, except: [:index]
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.all
end
#schools = Place.where("category = ?", "School")
#restaurants = Place.where("category = ?", "Restaurant")
#businesses = Place.where("category = ?", "Business")
end
Places Index.html.erb:
<% if user_signed_in? %>
<div class="row">
<h2>Newly Added Places</h2>
<%= form_tag places_path, :method => :get do %>
<%= text_field_tag :search, params[:search], placeholder: "Enter your zipcode or city", class: "search-query" %>
<%= submit_tag "Search Nearby", :name => nil, class: "btn"%>
<% end %>
<ul class="nav nav-tabs">
<li>Schools</li>
<li>Restaurants</li>
<li>Businesses</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<%= render :partial => "places", :locals => {:places_container => #schools} %>
</div>
<div class="tab-pane" id="tab2">
<%= render :partial => "places", :locals => {:places_container => #restaurants} %>
</div>
<div class="tab-pane" id="tab3">
<%= render :partial => "places", :locals => {:places_container => #businesses} %>
</div>
</div>
</div>
<br />
<% else %>
<%= render 'static_pages/home' %>
<% end %>
Places partial(_places.html.erb):
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Address</th>
<th>State</th>
<th>City</th>
<th>Type</th>
<th>Website</th>
</tr>
</thead>
<% places_container.each do |place| %>
<tr>
<th><%= image_tag place.image(:medium)%></th>
<th><%= link_to place.name, place %></th>
<td><%= place.address %></td>
<td><%= place.state %></td>
<td><%= place.city %></td>
<td><%= place.category %></td>
<td><%= place.website %></td>
<% if current_user.admin? %>
<td><%= link_to 'Edit', edit_place_path(place) %></td>
<td><%= link_to 'Destroy', place, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>
Your tabbed results are ignoring the search parameter because you aren't using the #places relation built from the search parameter. To fix, change this code:
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.all
end
#schools = Place.where("category = ?", "School")
#restaurants = Place.where("category = ?", "Restaurant")
#businesses = Place.where("category = ?", "Business")
end
to:
def index
if params[:search].present?
#places = Place.near(params[:search], 50, :order => :distance)
else
#places = Place.scoped # use 'scoped', not 'all', to avoid triggering the query immediately
end
#schools = #places.where("category = ?", "School")
#restaurants = #places.where("category = ?", "Restaurant")
#businesses = #places.where("category = ?", "Business")
end