I was following this tutorial and ran into difficulties.
I get the Routing Error by calling http://localhost:3000/home
Maybe I am just calling the wrong page.
I would grateful if somebody helps me.
Hier is my routes.rb:
Try::Application.routes.draw do
resources :uploads
root :to => "home#index"
end
uploads_controller.rb:
class UploadsController < ApplicationController
def home
end
def index
end
def create
#upload = Upload.new(params[:upload])
if #upload.save
render :json => { :pic_path => #upload.picture.url.to_s , :name => #upload.picture.instance.attributes["picture_file_name"] }, :content_type => 'text/html'
else
render :json => { :result => 'error'}, :content_type => 'text/html'
end
end
end
and views/home/index.html.erb:
<%= stylesheet_link_tag('jquery.fileupload-ui') %>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<%= javascript_include_tag 'jquery.fileupload', 'jquery.fileupload-ui' %>
<script type="text/javascript" charset="utf-8">
$(function () {
$('.upload').fileUploadUI({
uploadTable: $('.upload_files'),
downloadTable: $('.download_files'),
buildUploadRow: function (files, index) {
var file = files[index];
return $('<tr><td>' + file.name + '<\/td>' +
'<td class="file_upload_progress"><div><\/div><\/td>' +
'<td class="file_upload_cancel">' +
'<button class="ui-state-default ui-corner-all" title="Cancel">' +
'<span class="ui-icon ui-icon-cancel">Cancel<\/span>' +
'<\/button><\/td><\/tr>');
},
buildDownloadRow: function (file) {
return $('<tr><td><img alt="Photo" width="40" height="40" src="' + file.pic_path + '">' + file.name + '<\/td><\/tr>');
},
});
});
</script>
<div class="files">
<%= form_for #upload, :html => { :class => "upload", :multipart => true } do |f| %>
<%= f.file_field :picture %>
<div>Upload files</div>
<% end %>
<table class="upload_files"></table>
<table class="download_files"></table>
</div>
home_controller.rb:
class HomeController < ApplicationController
def index
#upload = Upload.new
end
end
Your routes file is saying that the root path i.e. '/' is going to home#index.
There is no route for '/home' Suggest you add:
match '/home' => 'uploads#home'
when you say root :to => "home#index" in routes file it means home controller index action
also your view file structure needs to be modifies to views/controller_name/index.html.erb:
Related
I am trying to integrate stripe into my rails app. Everything works well until I submit the form in which it looks like this when I do so:
Once I submit the form I am getting the following error:
I cannot figure out why it is doing this. When I check my stripe test dashboard nothing is there.
Here are some of the files:
donation.html.erb
<%= form_tag charges_path do %>
<div id="error_explanation">
<% if flash[:error].present? %>
<p><%= flash[:error] %></p>
<% end %>
</div>
<article>
<%= label_tag(:amount, 'Donation Amount:',class: 'donationHead') %>
<%= text_field_tag(:amount,"", class: 'form-control') %>
</article>
<article>
<%= hidden_field_tag(:stripeToken) %>
</article>
<button id='donateButton' class="btn btn-primary">Donate</button>
<% end %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<script>
var handler = StripeCheckout.configure({
key: '<%= Rails.configuration.stripe[:publishable_key] %>',
locale: 'auto',
name: 'Place4Grace',
image: '<%= asset_url "creative/small_logo.jpg" %>',
description: 'Thank you for your Donation!',
token: function(token) {
$('input#stripeToken').val(token.id);
$('form').submit();
}
});
$('#donateButton').on('click', function(e) {
e.preventDefault();
$('#error_explanation').html('');
var amount = $('input#amount').val();
amount = amount.replace(/\$/g, '').replace(/\,/g, '')
amount = parseFloat(amount);
if (isNaN(amount)) {
$('#error_explanation').html('<p>Please enter a valid amount in USD ($).</p>');
}
else if (amount < 5.00) {
$('#error_explanation').html('<p>Donation amount must be at least $5.</p>');
}
else {
amount = amount * 100; // Needs to be an integer!
handler.open({
amount: Math.round(amount)
})
}
});
$(window).on('popstate', function() {
handler.close();
});
</script>
Here is my stripe.rb
Rails.configuration.stripe = {
:publishable_key => 'pk_test...',
:secret_key => 'sk_test...'
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
routes.rb
resources :charges, only: [:new, :create]
And lastly here is my controller:
class ChargesController < ApplicationController
def new
end
def create
#amount = params[:amount]
#amount = #amount.gsub('$', '').gsub(',', '')
begin
#amount = Float(#amount).round(2)
rescue
flash[:error] = 'Charge not completed. Please enter a valid amount in USD ($).'
redirect_to root_path
return
end
#amount = (#amount * 100).to_i # Must be an integer!
if #amount < 500
flash[:error] = 'Charge not completed. Donation amount must be at least $5.'
redirect_to root_path
return
end
Stripe::Charge.create(
:amount => #amount,
:currency => 'usd',
:source => params[:stripeToken],
:description => 'Custom donation'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to root_path
end
end
UPDATE
Here is my route.rb:
Rails.application.routes.draw do
get 'dashboard/index'
get 'dashboard/new'
get 'dashboard/create'
get 'dashboard/show'
get 'dashboard/destroy'
get 'contacts/index'
get 'document/download'
get 'confirmation/confirmation'
get 'document/download'
root 'creatives#index'
get 'access/menu'
get 'access/login'
post 'access/attempt_login'
get 'access/logout'
get 'sessions/index'
get 'sessions/logout'
get 'sessions/profile'
get 'sessions/login'
get 'administrators/index'
get 'administrators/new'
resources :users do
member do
get :delete
end
end
resources :contacts do
member do
get :delete
end
end
resources :charges, only: [:new, :create]
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Update 2
Update 3
I don't know how to fix this or if this even matters but when you create a controller using rails in the terminal it creates a view automatically. I created a charges controller but the charges form is located in the creatives view not the charges view because it is a partial see image the page is donation.html.erb.
I have a form partial inside which I select associated users through a multiple: true collection select:
= f.collection_select(:user_ids, User.all, :id, :email, {selected: #limit_group.user_ids, include_blank: true}, {multiple: true, "data-placeholder" => "Add users to group"})
But how can I do this more efficiently to avoid big load times when the database has like thousands of users?
You'll be better using something called AutoComplete / LiveSearch with a text box (like Pardeep Saini mentioned).
We've done this before:
You could achieve this relatively simply:
= f.text_field :user_ids, placeholder: "Search for users"
You'd then have to use javascript:
#app/assets/javascripts/application.js
$(document).on("keyup", "input[type=text]#user_ids", function(){
$.getJSON("users/search", {name: $(this).val()}).done(function(json){
var users = [];
$.each(json.users, function(user) {
users.push("" + user.name + "");
});
$(".search").html(users).show();
});
});
$(document).on("click", ".search a", function(e) {
e.preventDefault();
// add hidden field with user name to form
});
You'd have to back it up with the relevant controller action:
#config/routes.rb
resources :users do
get :search, on: :collection
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def search
#users = User.where("name LIKE ?", "%" + params[:name] + "%")
respond_to do |format|
format.json (render json: #users.to_json)
end
end
end
The above code should be refactored.
--
To get this working with multiple values would be a little bit more involved. It could be done, but you'd have to do it like the tags setup in StackOverflow...
The way they do that is to basically use a similar principle to the above (each tag will be a returned piece of data from the search).
Here's the actual code we used in the cosmetics example above:
#app/assets/javascripts/extra/jquery.livesearch.js
(function($) {
$.searchbox = {}
$.extend(true, $.searchbox, {
settings: {
url: 'search',
param: 'search',
dom_id: '#livesearch',
minChars: 2,
loading_css: '#livesearch_loading',
del_id: '#livesearch_del'
},
loading: function() {
$($.searchbox.settings.loading_css).show()
},
idle: function() {
$($.searchbox.settings.loading_css).hide()
},
start: function() {
$.searchbox.loading()
$(document).trigger('before.searchbox')
},
stop: function() {
$.searchbox.idle()
$(document).trigger('after.searchbox')
},
kill: function() {
$($.searchbox.settings.dom_id).fadeOut(50)
$($.searchbox.settings.dom_id).html('')
$($.searchbox.settings.del_id).fadeOut(100)
},
reset: function() {
$($.searchbox.settings.dom_id).html('')
$($.searchbox.settings.dom_id).fadeOut(50)
$('#SearchSearch').val('')
$($.searchbox.settings.del_id).fadeOut(100)
},
process: function(terms) {
if(/\S/.test(terms)) {
$.ajax({
type: 'GET',
url: $.searchbox.settings.url,
data: {search: terms.trim()},
complete: function(data) {
$($.searchbox.settings.del_id).fadeIn(50)
$($.searchbox.settings.dom_id).html(data.responseText)
if (!$($.searchbox.settings.dom_id).is(':empty')) {
$($.searchbox.settings.dom_id).fadeIn(100)
}
$.searchbox.stop();
}
});
return false;
}else{
$.searchbox.kill();
}
}
});
$.fn.searchbox = function(config) {
var settings = $.extend(true, $.searchbox.settings, config || {})
$(document).trigger('init.searchbox')
$.searchbox.idle()
return this.each(function() {
var $input = $(this)
$input
.keyup(function() {
if ($input.val() != this.previousValue) {
if(/\S/.test($input.val().trim()) && $input.val().trim().length > $.searchbox.settings.minChars){
$.searchbox.start()
$.searchbox.process($input.val())
}else{
$.searchbox.kill()
}
this.previousValue = $input.val()
}
})
})
}
})(jQuery);
... and ...
#app/assets/javascripts/application.js
$(document).ready( function() {
var base_url = window.location.protocol + "//" + window.location.host;
$('#SearchSearch').searchbox({
url: base_url + '/search/',
param: 'search',
dom_id: '#livesearch',
loading_css: '#livesearch_loading'
})
});
$(document).on('click', '#livesearch_del', function() { $.searchbox.reset(); })
$(document).on('submit', '#SearchForm', function() { $.searchbox.kill(); });
$(document).on('click', '.livesearch_results tr', function() { window.location = $('a:first', this).attr('href'); });
The routes & controller:
#config/routes.rb
match 'search(/:search)', :to => 'products#search', :as => :search, via: [:get, :post]
#app/models/product.rb
class Product < ActiveRecord::Base
def self.search(search)
where("name LIKE ? OR description LIKE ?", "%#{search}%", "%#{search}%").take(5)
end
end
#app/controllers/product_controller.rb
class ProductsController < ApplicationController
def search
#products = Product.search params[:search]
respond_to do |format|
format.js { render :partial => "elements/livesearch", :locals => {:search => #products, :query => params[:search]} }
format.html {
render :index
}
end
end
end
The views:
#app/views/elements/_livesearch.html.erb
<div class="livesearch_container">
<table class="livesearch_results">
<% unless search.blank? %>
<% search.each_with_index do |item,i| %>
<% pos ||= '' %>
<% if (i == 0) then pos = 'first' end %>
<% if (i == search.size - 1) then pos += ' last' end %>
<tr data-link="<%= "/#{item.slug}" %>" class="<%= "#{pos}" %>">
<td class="image">
<% model = item.images.first || item.images.build %>
<%= image_tag(model.image.url(:thumb), :title => item.name, data: {"placement" => "left"}, :height => "85") %><br/>
</td>
<td class="information">
<%= link_to image_tag(item.brand.images.first.image.url(:thumb), :width => "55", :title => "View #{item.brand.name}"), "/#{item.brand.slug}", :class => "brand" if defined?(item.brand.images.first) %>
<div class="name"><%= link_to item.name, "/#{item.slug}" %></div>
</td>
<td class="price">
<%= number_to_currency(item.price, unit: "£") %>
</td>
</tr>
<% end %>
<tr class="results"><td colspan="3"><%= link_to "See all #{search.size} results here »", search_path(query) %></td></tr>
<% else %>
<tr class="results"><td colspan="3"><%= link_to 'No results found', search_path(query) %></td></tr>
<% end %>
</table>
</div>
I also made a gist here: https://gist.github.com/richpeck/2310ff3ab1ffcd6a9138
How can I use simple_form to filter a field, based on a previous fields value?
For instance, I have an Opportunities form, with two fields, Company and Contact.
Company Field:
<div class="form-group">
<%= f.association :company, collection: Company.all.order(:account), prompt: "", :label_method => :account, :value_method => :id %>
</div>
Contact Field:
<div class="form-group">
<%= f.association :contact, collection: Contact.all.order(:first_name), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
</div>
Here is what I want to do: If I select a company called "Deviant" from the Company field above, I want the Contact field to only display those contacts associated with the company called "Deviant".
I am trying something like this, but can't get it to work:
<div class="form-group">
<%= f.association :contact, collection: Contact.where("company_id = ?", params[:id]), prompt: "", :label_method => lambda { |contact| "#{contact.first_name} #{contact.last_name}" }, :value_method => :id %>
</div>
I don't know how to reference the value in the Company field.
How can I do this?
Thanks.
Update
Anyone? Surely this must be possible. This is a key functionality in any form. I would hope I don't need jQuery or something.
I think the best approach is to use ajax requests to update your contacts collection dinamically whenever the company's selected value is changed.
First you'll need an action in your contacts controller:
app/controllers/contacts_controller.rb
class ContactsController < ApplicationController
def contacts_list
if params[:company_id]
#contacts = Contact.where(company_id: params[:company_id])
else
#contacts = Contact.all
end
respond_with(#contacts) do |format|
format.json { render :json => #contacts.to_json(:only => [:id, :first_name, :last_name]) }
end
end
end
Add this to your routes:
config/routes.rb
post 'contacts_list' => "contacts#contacts_list", as: :contacts_list
Then use the coffeescript code bellow to populate your contacts' collection:
app/assets/javasctipts/companies.js.coffee
$(document).ready ->
if $("#opportunity_company_id")
populate_contacts()
$("#opportunity_company_id").change ->
populate_contacts()
populate_contacts = ->
$contacts_select = $("select#opportunity_contact_id")
$contacts_select.attr "disabled", "disabled"
company_id = $("select#opportunity_company_id").val()
if company_id is ""
$contacts_select.html "<option value=\"\">(select the company first)</option>"
else
$contacts_select.html "<option value=\"\">(loading contacts...)</option>"
data = {company_id: company_id}
data[window._auth_token_name] = window._auth_token
$.ajax "/contacts_list",
type: "post"
dataType: "json"
data: data
success: (contacts) ->
_html = '<option value="">Select the contact:</option>'
_html += '<option value="'+contact.id+'">'+contact.first_name + ' ' + contact.last_name + '</option>' for contact in contacts
$contacts_select.html _html
$contacts_select.removeAttr "disabled"
error: ->
alert 'Error trying to load contacts.'
Finally, inside your html's head tag:
<% if protect_against_forgery? %>
<script>
window._auth_token_name = "<%= request_forgery_protection_token %>";
window._auth_token = "<%= form_authenticity_token %>";
</script>
<% end %>
Hope it helps...
update:
Add the following line to your ApplicationController (app/controllers/application_controller.rb):
respond_to :html, :xml, :json, :js
I have a view which contain multiple links:
<% a.each do |q| %>
<%= link_to "stock it",
{ :action => "stock",
:qid => q.question_id,
:qur => q.question_answers_url,
:qti => q.title } ,
:remote => true %>
<div id="<%= "stock" + q.question_id.to_s %>"></div>
<% end %>
Each link generate AJAX-request. Here is a controller:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
respond_to do |format|
format.js { render :layout=>false }
end
end
Now return to the view. Each link has a 'div' with unique id='stock'. When user press the link I need to add text to specific div with corresponding id.
I have a stock.js.erb file:
$("#stock<number>").html("some text");
How can I pass div-id to stock.js.erb and how can I use it ?
Common use is to add object.id to your DOM id. That what you exactly did:
<div id="<%= "stock_#{q.question_id}" %>"></div>
Then in your controller you shoud define your question_id or your exact question:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
#question_id = params[:qid]
end
Now it will be shared with your stock.js.erb file:
$("#stock_<%= #question_id %>").html("some text");
I have nested routes like this :
map.resources :foo do |foo|
foo.resources :bar do |bar|
bar.resources :baz
end
end
i have list with pagination in the index action for each resource, i need to caches each of this pages, to do so i need the routes to be RESTful, how do i implements REFTful routes for it?
for example i want the route will be like this :
http://www.example.com/foo/:id/pages/:page_number
http://www.example.com/foo/:id/bar/:id/pages/:page_number
create custom_link_renderer.rb in app/helpers/
class CustomLinkRenderer < WillPaginate::LinkRenderer
def page_link(page, text, attributes = {})
#template.link_to text, "#{#template.url_for(#url_params)}/pages/#{page}", attributes
end
end
add this line to config/environment.rb
WillPaginate::ViewHelpers.pagination_options[:renderer] = 'CustomLinkRenderer'
I had the same problem. I wrote my own LinkRenderer like this to fully use nested routes.
class PaginationListLinkRenderer < WillPaginate::ViewHelpers::LinkRenderer
protected
def page_number(page)
unless page == current_page
if !#options[:params][:url].to_s.empty?
tag(:li, link(page, #options[:params][:url] + "?page=" + page.to_s))
else
tag(:li, link(page, page, :rel => rel_value(page)))
end
else
tag(:li, page, :class => "current")
end
end
def previous_or_next_page(page, text, classname)
if page
if !#options[:params][:url].to_s.empty?
tag(:li, link(text, #options[:params][:url] + "?page=" + page.to_s, :class => classname))
else
tag(:li, link(text, page, :rel => rel_value(page), :class => classname))
end
#tag(:li, link(text, page), :class => classname)
else
tag(:li, text, :class => classname + ' disabled')
end
end
def html_container(html)
tag(:ul, html, container_attributes)
end
end
Then you have to call will_paginate with this parameters:
<%= will_paginate :params => { :url => project_task_lists_path(#project) }, :renderer => PaginationListLinkRenderer %>
I hope this helps :)