When I am on tab 2 and I click for example on page 3, it refreshes the page and then I am back at tab 1. My guess is that I need AJAX to fix this problem, but I could use some help with that.
I tried some examples before, but none of them work.
Please help me how to sole this. Thank you in advance!
Controller:
class ProfilesController < ApplicationController
def show
#fullname = current_user.first_name + " " + current_user.last_name
#recipes = current_user.recipes.page(params[:recipes_page]).order("created_at DESC")
#favorites = current_user.favorites.page(params[:favorites_page]).order("created_at DESC")
end
end
Inside my view:
<div class="apple_pagination">
<%= will_paginate #recipes, param_name: "recipes_page" %>
</div>
<div class="apple_pagination">
<%= will_paginate #favorites, param_name: "favorites_page" %>
</div>
Try this:
<div class="apple_pagination">
<%= will_paginate #recipes, :remote => true , param_name: "recipes_page" %>
</div>
<div class="apple_pagination">
<%= will_paginate #favorites, :remote => true , param_name: "favorites_page" %>
</div>
Related
I am trying to make a search bar in order to find some cocktails by their name in my index. All I got is an empty array...
I believe my SQl request is not good... I'd need help please to make it working. Regards
Here is my code:
Search form:
<%= simple_form_for :query, url: cocktails_path, :method => :get do |f| %>
<%= f.input :search %>
<%= f.button :submit %>
<% end %>
cocktails controller:
def index
if params[:query].present?
#cocktails = Cocktail.all
#cocktail_search = #cocktails.where('cocktails.name LIKE ?', params[:query][:search])
binding.pry
else
#cocktails = Cocktail.all
end
end
the index view:
<% if #cocktail_search %>
<% #cocktail_search.each do |cocktail| %>
<div class="col-xs-12 col-sm-3">
<div class="card" style="background-image: linear-gradient(rgba(0,0,0,0.3), rgba(0,0,0,0.2)),
url('<%= cl_image_path cocktail.photo %>');">
<h2 class="card-description"><%= link_to cocktail.name, cocktail_path(cocktail)%></h2>
</div>
</div>
<% end %>
<% else %>
<% #cocktails.each do |cocktail| %>
<div class="col-xs-12 col-sm-3">
<div class="card" style="background-image: linear-gradient(rgba(0,0,0,0.3), rgba(0,0,0,0.2)),
url('<%= cl_image_path cocktail.photo %>');">
<h2 class="card-description"><%= link_to cocktail.name, cocktail_path(cocktail)%></h2>
</div>
</div>
<% end %>
<% end %>
This is my binding pry
#cocktail_search = #cocktails.where('cocktails.name LIKE ?', params[:query][:search])
If your table has column "name", then:
#cocktail_search = #cocktails.where('name LIKE ?', params[:query][:search])
should do the work.
When you're uncertain about what is wrong you can rails console and check things yourself, ex. Coctail.where("name like ?", "Mojito") and see if it returns expected result.
Since you use LIKE it seems like you want to find cocktails every if the search term matches only parts of the name. This can be archived by using % (see: Safe ActiveRecord like query).
Furthermore you might want to use a case-insensitive ILIKE instead of LIKE:
#cocktails.where('name ILIKE ?', "%#{params[:query][:search]}%")
Without the % you query is basically the same as
#cocktails.where(name: params[:query][:search])
that only returns exact matches.
I'm trying to make a basic search function for a simple product inventory app on Sinatra, but don't know how to make the controller and view to properly output all the products which have similar names to a results page.
SearchPage.erb:
<form action="/search", method="post">
<input type="text" name="product[name]">
Controller:
post '/search' do
#Products = Product.find_by(name: params[:product][:name])
#Products = Product.all(:name.like => "%#{params[:name]}%") #found this on another question
erb :"result"
end
Result.erb
<% #Products.each do |product| %>
<%=product.name %>
<%=product.details %>
EDIT: I was able to make search work based on the suggestion with the following code. Thanks!:
Search.erb View
<form action="/search", method="get">
<input type="text" name="search">
Controller
get '/search' do
#products = Product.all
if params[:search]
#products = Product.search(params[:search])
else
#products = Product.all
end
erb :'results'
end
Model
class Product < ActiveRecord::Base
def self.search(search)
where("name like ?", "%#{search}%")
end
Results.erb View
<% if #products.present? %>
<table>
<td>Product Name</td><td>Company</td>
<% #products.each do |product| %>
<tr><td><%=h product.name %> </td>
<td><%=h product.company.name %></td>
<% end %>
<% else %>
<p>There are no Products containing the term(s) <%= params[:search] %>.</p>
<% end %>
</table>
I notice off the bat you're using a POST method. There is an easier way to do create search functionality for your products. Try this:
Posts Controller:
#products = Product.all
if params[:search]
#products = Product.search(params[:search]).order("created_at DESC")
else
#products = Product.all.order('created_at DESC')
end
end
Posts Model (note: If you are using SQLite keep it as LIKE. If you are using Postgres, change LIKE to ILIKE)
def self.search(search)
where('name like :pat or content like :pat', :pat => "%#{search}%")
end
Search Form (Put into your Result.erb and edit as needed but keep as get method. I personally like using form helpers but you can create a normal form if you'd like)
<%= form_tag(products_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Posts" %>
<%= submit_tag "Search" %>
<% end %>
Render Results
<% if #products.present? %>
<%= render #products %>
<% else %>
<p>There are no posts containing the term(s) <%= params[:search] %>.</p>
<% end %>
Let me know if this works for you. If not, i'll try help some more.
What I am trying to do is show the 2 letter abbreviation code of the countries, i.e 'US'.
After the country is selected I need to show its state or province.
but I am having a problem.
My code looks like
<%= f.select :country_code, region_options_for_select(only_us_and_france) %>
and define this in helper:
def only_us_and_france
Carmen::Country.all.select{|c| %w{US FR}.include?(c.code)}
end
I am using Rails 4.1.0.
I have solved this by :
Step1: Generated migration
rails g migration addStateCodeFieldToAccounts state_code:string
Step2: Define a method inside controller
def subregion_options
render partial: 'subregion_select'
end
Step3: Declare in routes
resources :accounts do
collection do
get 'subregion_options'
end
end
Step4: In view
<div class="input-control select state_input" data-role="input-control">
<%= f.select :country, region_options_for_select(only_us_and_france) %>
</div>
<div class="input-control select state_input" data-role="input-control">
<%= render partial: 'subregion_select', locals: {parent_region: f.object.country} %>
</div>
Step5: Make partial subregion_select
<div id="account_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:order, :state_code, parent_region) %>
<% else %>
<%= text_field(:order, :state_code) %>
<% end %>
</div>
Step6: In my js file written this
$('select#account_detail_country').change(function(){
selectWrapper = $('#account_state_code_wrapper')
countryCode = $(this).val()
url = "/account_details/subregion_options?parent_region="+countryCode
console.log(url)
selectWrapper.load(url)
});
yeah and it works :) Hope this will help you.
I thought I understood Ajax in Rails 3 to a point but think I am confusing myself somewhere or misinterpreted something. My understanding is that if I want to call different content on the same page then i create a js.erb file for that particular action. For example if i have an action of tynewyddnews, I will have an tynewyddnews view and a tynewyddnews.js.erb file.
I then create a partial to render on that page and call that partial in my .js.erb file.
Example
View
<% #tynewyddpost.each do |t| %>
<li>
<% single = t.photos.first %>
<a class="photo" href="#"><%= image_tag(single.avatar.url(:thumbnail_news_images)) %></a>
<p><%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %></p>
<p class="date"><%= date_output(t.published_on) %></p>
</li>
<% end %>
<div class="post-item">
<h2><%= #tynewyddpostlatest.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpostlatest.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpostlatest.comments.html_safe %></p><a class="post-more" href="#">Continue Reading ยป</a>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpostlatest.published_on) %></p>
</li>
</ul>
</div>
</div>
So the historical posts go down the left hand side and the latest post goes in the center
.js.erb
<% if params[:type] == 'tynewyddnews' %>
jQuery('.post-item').html('<%= escape_javascript(render partial: 'tynewyddnewspost') %>');
<% end %>
Partial
<div class="post-item">
<h2><%= #tynewyddpost.title %></h2>
<div id="work-samples">
<% for photo in #tynewyddpost.photos %>
<%= image_tag(photo.avatar.url(:news_images), :class => 'work-sample') %>
<% end %>
</div>
<p class="post-description"><%= #tynewyddpost.comments.html_safe %></p>
<div class="post-item-panel">
<ul>
<li class="date">
<p><%= date_output(#tynewyddpost.published_on) %></p>
</li>
</ul>
</div>
</div>
Controller
def tynewyddnews
tynewyddpost = Post.tynewydd_posts.find(params[:post_id])
tynewyddpost.shift
#tynewyddpost = tynewyddpost
#tynewyddpostlatest = Post.tynewydd_posts.first
end
tynewydd_posts is a scope
scope :tynewydd_posts, :include => :department, :conditions => {"departments.name" => "Ty Newydd"}, :order => "posts.published_on DESC"
So my issue at the moment is when i try and render the page i get the error
Couldn't find Post without an ID
Apologies for the long post but if someone could point me in the right direction that would be great
Thanks
It looks to me like you're doing it way wrong, sorry. It doesn't need to be that complicated. I would start over from scratch with a much simpler example, and then build up from there.
I would do something like rails g scaffold post title:string and then do this, just in a browser console:
$.ajax({
url: "/posts/index"
}).done(function() {
console.log("done");
});
You should be able to see the data coming back through your browser's console. On the Rails side, that data is coming from here:
class PostsController < ApplicationController
def index
#posts = Post.all
# there might be more stuff here
end
end
Hopefully you understand what I'm talking about. If you don't, I'd recommend separately learning a little more about Rails and a little more about jQuery/ajax before trying to combine the two.
OK so it seems my issue was the way i was calling the id of a post and I also moved my ajax call into a separate action, setup all be it complicated is correct.
What i changed
<%= link_to t.title, tynewyddnews_path(:type => 'tynewyddnews'), :post_id => t.id, :remote => true %>
was changed to
<%= link_to t.title, my_path_path(:type => 'tynewyddnews', :id => t.id), :remote => true %>
Controller
I added a new action to handle the ajax call, finding a post by id
def my_path
#tynewyddpost = Post.find(params[:id])
end
Then in my partial I could use the #tynewyddpost instance variable
Hope this helps someone else
Here is the users show view where they are supposed to show up. ..
<section>
<div id= "purchases">
<%= render 'shared/micropost_form_purchase' %>
</div>
<div id="sales">
<%= render 'shared/micropost_form_sale' %>
</div>
</section>
<%= #sales %> <%# This is just to see if it outputs anything. It doesn't :( %>
<div id="purchases list">
<ol class="microposts">
<%= render #purchases unless #purchases.nil? %>
</ol>
</div>
<div id="sales list">
<ol class="microposts">
<%= render #sales unless #sales.nil? %>
</ol>
</div>
so the forms (partials) are loading fine, but then when I make a post, in either one, neither the purchases list nor the sales list shows up. I checked the database and they are being created along with an entry in the column indicating kind (either sale or purchase).
Here are the forms:
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
also, here is the show part of the users_controller.rb
def show
#user = User.find(params[:id])
#micropost=Micropost.new
#microposts = #user.microposts.paginate(page: params[:page])
end
and here is the show part of the microposts_controller.rb
def show
#micropost = Micropost.find(params[:id])
#microposts = Micropost.where(:user_id => #user.id)
#purchases= #microposts.collect{ |m| m if m.kind == "purchase"}.compact
#sales = #microposts.collect{ |m| m if m.kind == "sale"}.compact
end
additionally, with the help of this post (http://stackoverflow.com/questions/12505845/ruby-error-wrong-number-of-arguments-0-for-1#12505865) the variables #microposts, #purchases, and #sales are all outputting correctly in the console.
can anyone help me out?
edit: using scopes as suggested by the answer given works in the console (it outputs everything correctly, but they still don't show up in the view. Does this mean it is something wrong with my syntax for the users show page?
edit 2:
Here is the view/microposts/_micropost.html.erb code
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
</li>
I'm making some assumptions without seeing more of your code, but it looks like you could
write what you've shown a little differently. I'm assuming your databases are migrating
and have the required columns, e.g., Micropost#kind, Micropost#user_id, etc.
You can use scopes to refine a collection of microposts more expressively. It might be helpful to read
up about ActiveRecord scopes: http://guides.rubyonrails.org/active_record_querying.html#scopes.
class Micropost < ActiveRecord::Base
belongs_to :user
scope :purchases, where(:kind => "purchase")
scope :sales, where(:kind => "sale")
# your code
end
I'm also assuming your user has many microposts:
class User < ActiveRecord::Base
has_many :microposts
# your code
end
For your forms, I'd suggest attaching your hidden field to the form object (f.hidden_field) so
you don't have to specify the name as 'micropost[kind]'.
<%= form_for(#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field :kind, :value => "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
In MicropostsController#show, you can use your new scopes:
def show
#micropost = Micropost.find(params[:id])
#microposts = #user.microposts
#purchases = #microposts.purchases
#sales = #microposts.sales
end
You should also confirm that your MicropostsController#create action is actually adding
the microposts to the user sending the form (I'm assuming a current user method).
def create
#micropost = current_user.microposts.create(params[:micropost])
# yada
end
You can also confirm expected results on rails console after creating purchases or sales micropost with:
Micropost.purchases
Micropost.sales
Again, I could be missing something without seeing more of the code base.
Check Micropost.count, #purchases.count, #sales.count (by printing them in the controller, or some part of the view) to see if the records actually exist.
Also, if you want to render collections likes #sales and #purchases, you need to make sure that the model partial exists (_micropost.html.erb in your case). That is probably where you need to look for the view errors. For all you know, that file could be empty, thus no errors will show up at all.
The problem might also lie in your microposts#create (or whichever action that you are saving the micropost in), the micropost should be associated with the current_user:
#micropost = current_user.microposts.build(params[:micropost])
Taking this and your previous question into account, I suggest you go through the original code for the RoR tutorial again (and verify that all tests are passing) before taking it apart. You can always add new tests to it for your experiments and they will help in figuring out where you went wrong.