im trying to use ajax on acts_as_votable gem so the page doesnt refresh on a vote/upvote. I've adjused the controller methods for this, and added remote true on the links. However i think the only thing left are the two .js.erb files. ive looked around on here and the ruby documentation and i cant seem to find how to do it for this instance. thanks
VM23182:1 Uncaught ReferenceError: $ is not defined
at <anonymous>:1:1
at processResponse (application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:268)
at application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:196
at XMLHttpRequest.xhr.onreadystatechange (application-50000f29e1bf2752ae7e56dda39f10dd0f67a47aea5c3f07ed0d933f3e1a256a.js:251)
`$('.unlike_post').bind('ajax:success', function(){
$(this).parent().parent().find('.vote_count').html('<%= escape_javascript #post.votes_for.size.to_s %>');
$(this).closest('.unlike_post').hide();
$(this).closest('.votes').html(' <%= link_to "Like", like_post_path(#post), remote: true, method: :get, class: "like_post" %>');
});`
Started PUT "/tweets/60/like" for 127.0.0.1 at 2018-10-02 00:06:40 +0100
Processing by TweetsController#upvote as JS
Parameters: {"id"=>"60"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]]
↳ /Users/benherring/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Tweet Load (0.2ms) SELECT "tweets".* FROM "tweets" WHERE "tweets"."id" = $1 LIMIT $2 [["id", 60], ["LIMIT", 1]]
↳ app/controllers/tweets_controller.rb:57
(0.4ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = $1 AND "votes"."votable_type" = $2 AND "votes"."voter_id" = $3 AND "votes"."vote_scope" IS NULL AND "votes"."voter_type" = $4 [["votable_id", 60], ["votable_type", "Tweet"], ["voter_id", 3], ["voter_type", "User"]]
↳ app/controllers/tweets_controller.rb:58
ActsAsVotable::Vote Load (0.6ms) SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = $1 AND "votes"."votable_type" = $2 AND "votes"."voter_id" = $3 AND "votes"."vote_scope" IS NULL AND "votes"."voter_type" = $4 ORDER BY "votes"."id" DESC LIMIT $5 [["votable_id", 60], ["votable_type", "Tweet"], ["voter_id", 3], ["voter_type", "User"], ["LIMIT", 1]]
↳ app/controllers/tweets_controller.rb:58
(0.2ms) BEGIN
↳ app/controllers/tweets_controller.rb:58
ActsAsVotable::Vote Update (0.5ms) UPDATE "votes" SET "updated_at" = $1, "vote_flag" = $2 WHERE "votes"."id" = $3 [["updated_at", "2018-10-01 23:06:40.357671"], ["vote_flag", true], ["id", 10]]
↳ app/controllers/tweets_controller.rb:58
(1.3ms) COMMIT
↳ app/controllers/tweets_controller.rb:58
Rendering tweets/vote.js.erb
(0.4ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = $1 AND "votes"."votable_type" = $2 AND "votes"."vote_flag" = $3 [["votable_id", 60], ["votable_type", "Tweet"], ["vote_flag", true]]
↳ app/views/tweets/_icons.html.erb:5
(0.6ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = $1 AND "votes"."votable_type" = $2 AND "votes"."vote_flag" = $3 [["votable_id", 60], ["votable_type", "Tweet"], ["vote_flag", false]]
↳ app/views/tweets/_icons.html.erb:9
Rendered tweets/_icons.html.erb (5.7ms)
Rendered tweets/vote.js.erb (8.7ms)
Completed 200 OK in 40ms (Views: 21.0ms | ActiveRecord: 4.7ms)
resources :tweets do
member do
put "like", to: "tweets#upvote"
put "dislike", to: "tweets#downvote"
end
<div id="tweets">
<% #tweets.each do |tweet| %>
<div class="card">
<h4 class = "username"><%= link_to tweet.user.username, user_path(tweet.user) %></h4>
<p class="tweet-content"><%= tweet.content %></p>
<p class="date"><%= tweet.created_at.strftime("%B %d %Y, %l:%M%P") %></p>
<div class="icons">
<%= link_to like_tweet_path(tweet),remote: true , method: :put do %>
<div class="upvote"><i class="fas fa-thumbs-up"></i> <%= tweet.get_upvotes.size %></div>
<% end %>
<%= link_to dislike_tweet_path(tweet), remote: true, method: :put do %>
<div><i class="fas fa-thumbs-down"></i> <%= tweet.get_downvotes.size %></div>
<% end %>
</div>
</div>
<% end %>
</div>
def upvote
#tweet = Tweet.find(params[:id])
#tweet.upvote_by current_user
respond_to do |format|
format.html {redirect_to :tweets}
format.js {render layout: false}
# redirect_to :tweets
# redirect_to :tweets
# if request.xhr?
# head :ok
# else
end
end
def downvote
#tweet = Tweet.find(params[:id])
#tweet.downvote_by current_user
respond_to do |format|
format.html {redirect_to :tweets}
format.js {render layout: false}
# redirect_to :tweets
end
end
It looks like the way you initially started on is to attach handlers to the buttons that listen for successful requests. This is a fair way to do it, but - since you're already using Rails UJS - there's a possibly "better" way.
With Rails UJS, JS files returned from a remote action are automatically executed. In my opinion, a more idiomatic Rails way to do this is as follows:
Extract out the icons into their own template:
<div id="tweets">
<% #tweets.each do |tweet| %>
<div id="tweet-<%= tweet.id %>" class="card">
<h4 class = "username"><%= link_to tweet.user.username, user_path(tweet.user) %></h4>
<p class="tweet-content"><%= tweet.content %></p>
<p class="date"><%= tweet.created_at.strftime("%B %d %Y, %l:%M%P") %></p>
<%= render 'icons', tweet: tweet %>
</div>
<% end %>
</div>
tweets/_icons.html.erb:
<div class="icons">
<%= link_to like_tweet_path(tweet),remote: true , method: :put do %>
<div class="upvote"><i class="fas fa-thumbs-up"></i> <%= tweet.get_upvotes.size %></div>
<% end %>
<%= link_to dislike_tweet_path(tweet), remote: true, method: :put do %>
<div class="downvote"><i class="fas fa-thumbs-down"></i> <%= tweet.get_downvotes.size %></div>
<% end %>
</div>
Then, in your upvote/downvote controller actions you would format.js { render 'vote' } which would live at tweets/vote.js.erb and look like:
document.querySelector('#tweet-<%= #tweet.id %> .icons').outerHTML = '<%= j render('icons', tweet: #tweet) %>';
At this point, you're now free to modify tweets/_icons.html.erb to provide extra functionality (e.g. visual feedback on votes or changing the URL of the links to undo a vote).
Old jQuery method
Keeping this "older" jQuery method for those people who encounter a similar issue and are using jQuery. Though, really, you probably don't need it.
$('#tweet-<%= #tweet.id %> .icons').replaceWith('<%= j render('icons', tweet: #tweet) %>');
Related
I am also using Devise. I update the seller and the avatar image doesn't appear on the sellers page. This has been going on a while.
This is the server output in the terminal:
Started GET "/farmers" for 127.0.0.1 at 2020-08-06 19:26:57 +0100
(0.5ms) SELECT sqlite_version(*)
Processing by UserController#farmers as HTML
Rendering user/farmers.html.erb within layouts/application
User Load (2.6ms) SELECT "users"."farm_name", "avatar", "users"."about_farm", "users"."farm_type", "users"."county" FROM "users" WHERE "users"."role" = ? [["role", 1]]
↳ app/views/user/farmers.html.erb:6
ActiveStorage::Attachment Load (2.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" IS NULL AND "active_storage_attachments"."record_type"
= ? AND "active_storage_attachments"."name" = ? LIMIT ? [["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
↳ app/views/user/farmers.html.erb:28
CACHE ActiveStorage::Attachment Load (0.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" IS NULL AND "active_storage_attachments"."record_type" = ? AND "active_storage_attachments"."name" = ? LIMIT ? [["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
↳ app/views/user/farmers.html.erb:28
Rendered user/farmers.html.erb within layouts/application (Duration: 848.9ms | Allocations: 13223)
[Webpacker] Everything's up-to-date. Nothing to do
User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?
[["id", 18], ["LIMIT", 1]]
↳ app/views/layouts/application.html.erb:47
Rendered layouts/_search.html.erb (Duration: 1.3ms | Allocations: 173)
Completed 200 OK in 1297ms (Views: 1217.8ms | ActiveRecord: 30.9ms | Allocations: 21165)
Here is a link to the code for the view page: https://gist.github.com/Josebuendia/21ba9b9a7e6b67bf593ed44675fbb97c
And the controller that fetches the data: https://gist.github.com/Josebuendia/b22486363fdffe470b27b34daad2cc9b
user = User.last
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<User id: 18, email: "farmer12#gmail.com", created_at: "2020-08-05 16:47:08", updated_at: "2020-08-06 17:56:28", role: 1, farm_name: "Glen Valley Farm", farmers_picture: nil, about_farm: "My farm sells organic artisan beef and lamb. I'm l...", farm_type: "Mixed", county: "Wicklow">
irb(main):013:0> user.avatar.attached?
ActiveStorage::Attachment Load (3.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ?
AND "active_storage_attachments"."name" = ? LIMIT ? [["record_id", 18], ["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
=> true
irb(main):014:0>
ents" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ?
AND "active_storage_attachments"."name" = ? LIMIT ? [["record_id", 18], ["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
=> true
The weird thing is that the data is fetched correctly with the items even though that's also using the Active Storage gem!
The form elements in the items form is form.
In the other forms for the users it is f.
Though, I doubt that makes a difference.
The view page code:
<p id="notice"><%= notice %></p>
<div id="itemsContainer">
<h1>Our Farmers</h1>
<% #users.each do |user| %>
<div class="itemhols">
<%
=begin%>
<h1><%= user.email %></h1>
<%
=end%>
<!--Data to include on farmers: name, pic, about, type, county-->
<h2><%= user.farm_name %></h2>
<%
=begin%>
<p><%= image_tag user.farmers_picture if user.farmers_picture.present? %></p>
<%
=end%>
<%
=begin%>
<%= image_tag user.avatar.variant(resize: "200x200").processed if user.avatar.attached? %>
<%
=end%>
<% if user.avatar.attached? %>
<image src="<%=(url_for(user.avatar))%>" class="itemholsIm">
<% end %>
<p><%= user.about_farm %></p>
<p><%= user.farm_type %></p>
<p><%= user.county %></p>
<%
=begin%>
<%= link_to 'Show', user, :class => "button", :role => "button" %>
<%
=end%>
<%
=begin%>
<--<%= link_to 'Show', item, :class => "button", :role => "button" %>
<%
=end%>
</div>
<% end %>
</div>
And the controller that fetches the data:
class UserController < ApplicationController
def login
session[:login] = 1
session[:cart] = nil
#Changed the line below to Seller Login sucessfull! from "Admin Login sucessfull!"
flash[:notice] = "Seller Login sucessfull!"
redirect_to :controller => :items
end
def logout
session[:login] = nil
session[:cart] = nil
flash[:notice] = "You have been successfully logged out!!"
redirect_to :controller => :items
end
#iteration for farmers page
def farmers
##users = User.where(role: 1)
#users = User.select(:farm_name, :avatar, :about_farm, :farm_type, :county).where(role: 1)
end
def search
st = "%#{params[:q]}%"
#users = User.where("email like ?", st)
end
def show
end
#def farmers
# #user = User.find(params[:id])
# FIXME get the view working for the farmers page
#end
def upgrade_admin
#user.update_attribute(:adminrole, true)
redirect_to :action => :admin_users
end
def downgrade_admin
#user.update_attribute(:adminrole, false)
redirect_to :action => :admin_users
end
end
This method is most likely the culprit...although there may be other issues
def farmers
##users = User.where(role: 1)
#users = User.select(:farm_name, :avatar, :about_farm, :farm_type, :county).where(role: 1)
end
Because ActiveStorage attachments are polymorpic relationships, you need to (at the very least) include the user id in the SELECT. It also seems like, based on your wording, that it worked once but at some point stopped working. My guess is it stopped working when you commented out this line...
#users = User.where(role: 1)
I would suggest just loading the entire user to avoid future problems...
def farmers
#users = User.where(role: 1)
end
Or, add :id to the select (without :avatar)
def farmers
##users = User.where(role: 1)
#users = User.select(:id, :farm_name, :about_farm, :farm_type, :county).where(role: 1)
end
Note :avatar is not needed because it isn't actually a column in the database.
I have installed the carrierwave gem on my rails app and also I have implemented this. The only alteration I made was the form:
<div class="container">
<div class="panel panel-default">
<div class="panel-body">
<div class="text-center">
<% unless current_store.account.images.blank? %>
<% #account.images.each_with_index do |image, index| #grab the index %>
<div class="img-thumbnail">
<%= image_tag(image.url(:mini)) %>
<br><%= link_to t("store_item_edit_2"), remove_images_path(#account, index),
data: { confirm: I18n.t("store_item_edit_3") },
:method => :delete %></div>
<% end %>
<% end %>
<% unless #account.blank? %>
<%= form_for #account, url: create_image_path, :html => {:id => "form"}, method: :post do |form| %>
<% if #account.errors.any? %>
<div class="centerList">
<div id="error_explanation">
<h2><%= pluralize(account.errors.count, "error") %> <%= t 'store_item_edit_4' %></h2>
<% #account.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
</div>
<div class="form-group">
<div class="pull-left">
<label class="btn btn-primary"><%= t 'store_item_edit_5' %><span style="display:none;">
<%= form.file_field :images, multiple: true, id: "uploads" %></span></label>
<%= form.submit '', :style => "display: none;" %>
<% end %>
<% end %>
</div>
</div>
</div>
<script>
document.getElementById("uploads").onchange = function() {
document.getElementById("form").submit();
};
</script>
All works well, I can upload and view the images! The only problem is when I uploaded new images the old ones get deleted.
I added an images column to the accounts table
create_table "accounts", force: :cascade do |t|
t.string "images", default: [], array: true
end
I even tried the following skip callback but that didn't work also:
class Account < ApplicationRecord
mount_uploaders :images, AttachmentUploader
skip_callback :commit, :after, :remove_previously_stored_avatar, :on=> :update, raise: false
end
this is my image controller:
class ImagesController < ApplicationController
before_action :set_image
def add_images
render :template => 'accounts/add_images'
end
def create
add_more_images(images_params[:images])
flash[:error] = "Failed uploading images" unless #account.save
redirect_back(fallback_location: root_path)
end
def destroy
remove_image_at_index(params[:id].to_i)
flash[:error] = "Failed deleting image" unless #account.save
redirect_back(fallback_location: root_path)
end
private
def set_image
#account = Account.find(params[:id])
end
def add_more_images(new_images)
#account = Account.find(params[:id])
images = #account.images
images += new_images
#account.images = images
end
def remove_image_at_index(index)
remain_images = #account.images # copy the array
deleted_image = remain_images.delete_at(index) # delete the target image
deleted_image.try(:remove!) # delete image from S3
#account.images = remain_images # re-assign back
end
def images_params
params.require(:account).permit({images: []}) # allow nested params as array
end
end
and this is what I get at the console:
Started POST "/store/accounts/1/images/create" for 127.0.0.1 at 2018-03-12 15:21:10 +0200
Processing by ImagesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gfqy6KjWtTc3eR2Z9GXJ4/Wx/REzn6mqA+T1q+qGCgXnHkggnsTM4DBPqHKnEmhMPEybL+kTclIoFy1e9+oWiw==", "account"=>{"images"=>[#<ActionDispatch::Http::UploadedFile:0x007ff19f3b75c0 #tempfile=#<Tempfile:/var/folders/hq/pr4rt14n7s31v3f6292wtjm00000gn/T/RackMultipart20180312-3771-jyl4gh.jpg>, #original_filename="image4.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"account[images][]\"; filename=\"image4.jpg\"\r\nContent-Type: image/jpeg\r\n">]}, "id"=>"1"}
Account Load (0.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
CACHE Account Load (0.0ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) BEGIN
Store Load (0.4ms) SELECT "stores".* FROM "stores" WHERE "stores"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Account Exists (0.6ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."business_name" = $1 AND ("accounts"."id" != $2) LIMIT $3 [["business_name", "Example Account"], ["id", 1], ["LIMIT", 1]]
Account Exists (0.4ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."business_description" = $1 AND ("accounts"."id" != $2) LIMIT $3 [["business_description", "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. "], ["id", 1], ["LIMIT", 1]]
Account Exists (0.3ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."street" = $1 AND ("accounts"."id" != $2) LIMIT $3 [["street", "Stylianou Apostolidi 25"], ["id", 1], ["LIMIT", 1]]
SQL (0.6ms) UPDATE "accounts" SET "images" = $1, "updated_at" = $2 WHERE "accounts"."id" = $3 [["images", "{NULL,NULL,image4.jpg}"], ["updated_at", "2018-03-12 13:21:11.408738"], ["id", 1]]
(0.4ms) COMMIT
Any ideas how I can make this work?
I solved the issue of previous images being destroyed by adding this to the model with the images attached. I am a novice coder so I can't promise it is the fastest, but it does work. I have the images stored as JSON.
before_validation { self.previous_images }
before_save { self.add_previous_images }
def previous_images
if !self.images.blank?
#images = self[:images]
end
end
def add_previous_images
if defined?(#images) and !#images.blank?
#images.each do |a|
if !self[:images].include?(a)
self[:images] << a
end
end
end
end
I have a checkout sequence in my app like this:
Cart - The user's tax is calculated and they hit a checkout button
charges#address - There is a form to update the shipping address in the user table
charges#shipping - The user chooses a shipping method (which updates order.total in the database)
charges#new - Stripe actually makes a charge
My issue is that, for some reason, the charges#shipping (step 3 is skipped, it goes from 2 to 4) is being skipped over entirely. The information for each step is below.
Step 2 Information
The form:
<%= simple_form_for(#user, url: user_path(#user), html: { method: :put }) do |f| %>
<div class="form-inputs text-left">
<div class="form-group col-sm-6">
<%= f.label :street_address_1 %>
<%= f.text_field :street_address_1, class: "form-control" %>
</div>
<div class="form-group col-sm-6">
<%= f.label :street_address_2 %>
<%= f.text_field :street_address_2, class: "form-control" %>
</div>
<div class="form-group col-sm-6">
<%= f.label :city %>
<%= f.text_field :city, class: "form-control" %>
</div><div class="form-group col-sm-3 col-xs-6">
<%= f.label :state %>
<%= f.text_field :state, class: "form-control" %>
</div><div class="form-group col-sm-3 col-xs-6">
<%= f.label :zip %>
<%= f.text_field :zip, class: "form-control" %>
</div><div class="form-group col-sm-6">
<%= f.label :provence %>
<%= f.text_field :provence, class: "form-control" %>
</div><div class="form-group col-sm-6">
<%= f.label :country %>
<%= f.text_field :country, class: "form-control" %>
</div><div class="form-group">
<%= f.hidden_field :has_shipping, value: true %>
</div>
</div> <!-- form inputs -->
<%= f.button :submit, "Calculate Shipping" %>
<% end %>
The method in users_controller which should be sending it to the charges#shipping page, but it ends up on charges#new:
def update
#user = User.find(params[:id])
#user.update_attributes(account_update_params)
if #user.update(account_update_params)
redirect_to charges_shipping_path
else
render :back
flash[:notice] = "Something is amuck."
end
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password, :phone, :admin, :stripe_customer_id, :street_address_1, :street_address_2, :city, :state, :zip, :provence, :country, :has_shipping)
end
Here's what's happening in the server:
Started PUT "/users/1" for ::1 at 2017-05-16 10:04:10 -0700
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"R2ZDErL9UQ6nPNyYDI9FDeOp0x29t+/STWIkTKeShz2WWdO8kWu+z6V5NS/EKI6uiLcCAQBbwbsRMlhGs8v2VA==", "user"=>{"street_address_1"=>"10 Oak View Drive", "street_address_2"=>"Test", "city"=>"Aliso Viejo", "state"=>"CA", "zip"=>"92656", "provence"=>"", "country"=>"US", "has_shipping"=>"true"}, "commit"=>"Calculate Shipping", "id"=>"1"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
(0.1ms) commit transaction
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/charges/shipping
Completed 302 Found in 5ms (ActiveRecord: 0.3ms)
Started GET "/charges/shipping" for ::1 at 2017-05-16 10:04:10 -0700
Processing by ChargesController#shipping as HTML
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Order Load (0.1ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
CACHE (0.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
(0.1ms) begin transaction
OrderItem Load (0.1ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."order_id" = ? [["order_id", 5]]
Product Load (0.0ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", "t"], ["id", 2]]
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", "t"], ["id", 1]]
(0.0ms) commit transaction
156.95
(0.0ms) begin transaction
(0.0ms) commit transaction
Redirected to http://localhost:3000/charges/new
CACHE (0.0ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."order_id" = ? [["order_id", 5]]
CACHE (0.0ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", true], ["id", 2]]
CACHE (0.0ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", true], ["id", 1]]
Completed 302 Found in 1965ms (ActiveRecord: 0.6ms)
Started GET "/charges/new" for ::1 at 2017-05-16 10:04:12 -0700
Processing by ChargesController#new as HTML
Order Load (0.1ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
Rendered charges/_shipping.html.erb (2.1ms)
Rendered charges/new.html.erb within layouts/application (3.1ms)
CACHE (0.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
(0.1ms) SELECT COUNT(*) FROM "order_items" WHERE "order_items"."order_id" = ? [["order_id", 5]]
CACHE (0.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" = ? LIMIT 1 [["id", 5]]
OrderItem Load (0.1ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."order_id" = ? [["order_id", 5]]
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", "t"], ["id", 2]]
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."active" = ? AND "products"."id" = ? LIMIT 1 [["active", "t"], ["id", 1]]
Rendered layouts/_cart_text.html.erb (6.1ms)
Completed 200 OK in 82ms (Views: 80.6ms | ActiveRecord: 0.6ms)
Here's the form in step 3 (the one being skipped, though all that really matters here is that it's a form_for(#order):
<h3>Shipping Rates</h3>
<% shipping_choices = [] %>
<% #ups_rates.each do |rate| %>
<% choice = [] %>
<% choice << number_to_currency(rate[1]/100) %>
<% choice << number_to_currency(rate[1]/100).to_s + " - " + rate[0].to_s %>
<% shipping_choices << choice %>
<% end %>
<%= simple_form_for order_path(#order) do |f| %>
<div class="row">
<div class="form-inputs text-left">
<div class="form-group col-sm-6">
<%= f.collection_radio_buttons :shipping, shipping_choices, :first, :last, item_wrapper_class: :block_radio_button_collection %>
</div>
</div> <!-- form inputs -->
</div> <!-- choices row -->
<div class="row">
<%= f.button :submit, "Calculate Shipping" %>
</div>
<% end %>
And here's the order#update method:
def update
#order = current_order
if #order.update(order_params)
redirect_to charges_address_path
else
render :back
flash[:notice] = "Something is amuck."
end
end
This is a very strange problem for me. Can anyone see where I'm going wrong?
Additional Information
As requested, here is my (unfortunately long) `charges#shipping` method:
def shipping
#user = current_user
#products = current_order.order_items.all
#order = current_order
if #order.update(order_params)
new_total = #order.total + #order.shipping
#order.update_attributes(total: new_total)
redirect_to new_charge_path
else
render :back
flash[:notice] = "Something is amuck."
end
#envelope_weight = 0
#not_envelope = 0
#products.each do |thing|
if thing.product.envelope
#envelope_weight += thing.product.weight
else
#not_envelope += 1
end
end
if #not_envelope == 0
# shipping for envelope
else
packages = []
#products.each do |thing|
unless thing.product.envelope
if thing.id == 1
packages << ActiveShipping::Package.new( (thing.product.weight + #envelope_weight ) * 16,
[thing.product.box_length, thing.product.box_width, thing.product.box_depth],
units: :imperial)
else
packages << ActiveShipping::Package.new( thing.product.weight * 16,
[thing.product.box_length, thing.product.box_width, thing.product.box_depth],
units: :imperial)
end # envelope weight if else
end #unless
end ## each do
end # not envelope if/else
origin = ActiveShipping::Location.new( country: 'US', state: 'CO', city: 'Sedalia', zip: '80135')
if #user.country == 'US'
destination = ActiveShipping::Location.new( country: #user.country, state: #user.state, city: #user.city, zip: #user.zip)
else
destination = ActiveShipping::Location.new( country: #user.country, province: #user.state, city: #user.city, postal_code: #user.zip)
end # if/else for country
ups = ActiveShipping::UPS.new(login: 'lizbayardelle', password: 'UPSpassw0rd', key: '3D287D7B39D0D398')
ups_response = ups.find_rates(origin, destination, packages)
#ups_rates = ups_response.rates.sort_by(&:price).collect {|rate| [rate.service_name, rate.price]}
usps = ActiveShipping::USPS.new(login: '380LINCH6422')
usps_response = usps.find_rates(origin, destination, packages)
#usps_rates = usps_response.rates.sort_by(&:price).collect {|rate| [rate.service_name, rate.price]}
end
First you redirected from UsersController#update to ChargesController#shipping, it went into the shipping action where the condition for if #order.update(order_params) became true as order_params is nil here and hence it redirected to ChargesController#new
When you do a redirect_to in rails, it redirects as a GET request. When you submit a form, it will be POST/PUT by default(unless you change it).
You can even see in your logs, how all redirects are going in as GET.
It is not advisable to use same action for both. If you do want to use same action make sure you are adding a check for request.method=='GET' or request.method=='POST' in them.
From what I see in your shipping action code, it was written to handle form submits(POST) and not for handling GET requests via redirects.
So either handle it logically or seperate it into seperate actions, one to render the form and other to handle the form submit.
P.S. Also do not forget to add 'and return' after each redirect.
redirect_to charges_shipping_path and return
My params hash looks like this: Parameters: {"id"=>"6", "bonus_id"=>"2", "bonus_title"=>"deposit-match-row"}, and this is my controller:
def load_more_bonuses
#more_casinos = []
#bonus_title = params[:bonus_title]
bonus = Bonus.find(params[:bonus_id])
#more_casinos << bonus.casinos.where('casinos.id >?', params[:id]).order(id: :asc).limit(6).uniq
respond_to do |format|
format.js
end
end
I get the following error: ActiveRecord::RecordNotFound (Couldn't find Bonus with 'id'=) In rails console everything works fine, doing: bonus = Bonus.find(2) gives me my bonus record. What's wrong with the code above, what can be done to get rid of the error? Thanks.
EDIT
Full server log:
Started GET "/load_more_bonuses?id=6&bonus_id=2&bonus_title=deposit-match-row" for 127.0.0.1 at 2017-04-24 12:08:00 +0300
Processing by BonusesController#load_more_bonuses as JS
Parameters: {"id"=>"6", "bonus_id"=>"2", "bonus_title"=>"deposit-match-row"}
Started GET "/load_more_bonuses" for 127.0.0.1 at 2017-04-24 12:08:00 +0300
Processing by BonusesController#load_more_bonuses as JS
Casino Load (7.2ms) SELECT "casinos".* FROM "casinos" WHERE "casinos"."casino_of_the_month" = $1 LIMIT $2 [["casino_of_the_month", true], ["LIMIT", 1]]
Casino Load (1.4ms) SELECT "casinos".* FROM "casinos" WHERE "casinos"."casino_of_the_month" = $1 LIMIT $2 [["casino_of_the_month", true], ["LIMIT", 1]]
Bonus Load (1.2ms) SELECT "bonuses".* FROM "bonuses" WHERE "bonuses"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
Bonus Load (15.7ms) SELECT "bonuses".* FROM "bonuses" WHERE "bonuses"."id" = $1 LIMIT $2 [["id", nil], ["LIMIT", 1]]
Rendering bonuses/load_more_bonuses.js.erb
Completed 404 Not Found in 27ms (ActiveRecord: 17.1ms)
ActiveRecord::RecordNotFound (Couldn't find Bonus with 'id'=):
Casino Load (2.2ms) SELECT DISTINCT "casinos".* FROM "casinos" INNER JOIN "casino_bonuses" ON "casinos"."id" = "casino_bonuses"."casino_id" WHERE "casino_bonuses"."bonus_id" = $1 AND (casinos.id >'6') ORDER BY "casinos"."id" ASC LIMIT $2 [["bonus_id", 2], ["LIMIT", 6]]
app/controllers/bonuses_controller.rb:75:in `load_more_bonuses'
Rendering /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb
Rendering /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.text.erb
Rendered /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.text.erb (0.7ms)
Rendering /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb
Rendered /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.8ms)
Rendering /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb
Rendered /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (1.2ms)
Rendered /home/spacechick/.rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb (26.8ms)
(0.5ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
(0.4ms) SELECT SUM("ratings"."score") FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
CACHE (0.0ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
CACHE (0.0ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
CACHE (0.0ms) SELECT SUM("ratings"."score") FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
CACHE (0.0ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."casino_id" = $1 [["casino_id", 10]]
Rendered bonuses/_load_more_casinos_list.html.erb (150.9ms)
Rendered bonuses/load_more_bonuses.js.erb (154.1ms)
Completed 200 OK in 193ms (Views: 159.7ms | ActiveRecord: 11.5ms)
EDIT 2
_load_more_casinos_list.html.erb:
<% #more_casinos.flatten.uniq.sort_by{ |id| id[:id] }.reverse!.take(6).each do |casino| %>
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<div class="bonus-casino-index-item" data-id="<%= casino.id %>">
<div class="bonus-casinos-index-item-flip">
<div class="front">
<div class="bonus-casino-background" style="background-color: <%= casino.background_color %>">
<div class="bonus-info-sign">
<span class="glyphicon glyphicon-info-sign"></span>
</div>
<% if casino.new === true %>
<div class="bonus-casino-new"></div>
<% elsif casino.hot === true %>
<div class="bonus-casino-hot"></div>
<% elsif casino.exclusive === true %>
<div class="bonus-casino-exclusive"></div>
<% end %>
<div class="bonus-casino-logo">Logo will be here</div>
<div class="bonus-casino-rating">
<div class="rateit" data-rateit-value="<%= casino.average_rating %>" data-rateit-ispreset="true" data-rateit-readonly="true" data-rateit-mode="font" style="font-size:20px"></div>
</div>
<div class="bonus-casino-bonus-info">
<%= casino.bonus_info %>
</div>
</div>
</div>
<div class="back">
<div class="bonus-casino-background-back">
<div class="bonus-casino-back-close">
<span class="glyphicon glyphicon-remove-sign"></span>
</div>
<p class="bonus-casino-bonus-info-back"><%= casino.bonus_info.truncate(50) %></p>
<p class="bonus-casino-average-rating">Score: <%= casino.average_rating.round(2) %></p>
<div class="bonus-casino-bonus-description"><%= strip_tags(casino.description).truncate(120) %></div>
</div>
</div>
</div>
<div class="bonuses-page-casino-list-links">
<%= link_to 'Review', casino, class: 'bonus-casino-index-item-review' %>
<%= link_to 'Join now', '#', class: 'bonus-casino-index-item-join-now' %>
</div>
</div>
</div>
<% end %>
EDIT 3
puts #more_casinos gives me:
Casino Load (4.1ms) SELECT "casinos".* FROM "casinos" WHERE "casinos"."casino_of_the_month" = $1 LIMIT $2 [["casino_of_the_month", true], ["LIMIT", 1]]
Casino Load (1.8ms) SELECT DISTINCT "casinos".* FROM "casinos" INNER JOIN "casino_bonuses" ON "casinos"."id" = "casino_bonuses"."casino_id" WHERE "casino_bonuses"."bonus_id" = $1 AND (casinos.id >'6') ORDER BY "casinos"."id" ASC LIMIT $2 [["bonus_id", 2], ["LIMIT", 6]]
Bonus Load (0.4ms) SELECT "bonuses".* FROM "bonuses" WHERE "bonuses"."id" = $1 LIMIT $2 [["id", nil], ["LIMIT", 1]]
#<Casino:0x000000082c8820>
And load_more_bonuses.js.erb:
<% if #more_casinos.any? %>
$('#<%= #bonus_title.parameterize %>-row').append('<%= j render 'bonuses/load_more_casinos_list' %>');
<% end %>
EDIT 4
Ajax call in application.js
$('.bonus-casinos-load-more').click(function () {
var lastId = $(this).parent().parent().parent().children('.first-row').children().last().children().attr('data-id');
var bonusId = $(this).attr('data-id');
var bonusTitle = $(this).parent().parent().parent().children('.first-row').attr('id');
$.ajax({
type: 'GET',
url: $(this).attr('href'),
data: {
id: lastId,
bonus_id: bonusId,
bonus_title: bonusTitle
},
dataType: 'script'
});
});
The problem should be related to the view, because in your log, it sends 2 requests.
One requests with legal querystring, 1 request querystring is empty.
Started GET "/load_more_bonuses?id=6&bonus_id=2&bonus_title=deposit-match-row" for 127.0.0.1 at 2017-04-24 12:08:00 +0300
Processing by BonusesController#load_more_bonuses as JS
Parameters: {"id"=>"6", "bonus_id"=>"2", "bonus_title"=>"deposit-match-row"}
Started GET "/load_more_bonuses" for 127.0.0.1 at 2017-04-24 12:08:00 +0300
In your view file, it will sent another request, but without paramters.
It's send by the ajax call, then check the parameters, find out why it's empty. Add some console.log at the js code.
I have Product model with some params (price, category_id, image etc.).
When creating a new product in the form partial, category is being selected via select_tag and image gets uploaded via Carrierwave, image uploader. Bad things happens when I send user to crop the uploaded image in crop.html.erb file. There user crops image, clicks submit, which uses path as update (not very sure which HTTP protocol), and gets redirected into product edit page, since product somehow lost category_id parameter. Form shows error to select a category (all other params from input_fields does not get lost).
My tries was like defining the crop method and setting category there, but no luck...
products_controller.rb:
def edit
#categories = Category.all
end
def create
#product = Product.new(product_params)
#product.category_id = params[:category_id]
#product.user_id = current_user.id
respond_to do |format|
if #product.save
if params[:product][:image].present?
format.html { render :crop }
else
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
end
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
def update
#product.category_id = params[:category_id]
respond_to do |format|
if #product.update(product_params)
if params[:product][:image].present?
format.html { render :crop }
else
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
#products = Product.all
ActionCable.server.broadcast 'products',
html: render_to_string('store/index', layout: false)
end
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
crop.html.erb (in products folder):
<%= image_tag #product.image_url(:large), id: "cropbox" %>
<h4>Preview</h4>
<div style="width:300px; height:200px; overflow:hidden;">
<%= image_tag #product.image.url(:large), :id => "preview" %>
</div>
<%= form_for #product do |f| %>
<% %w[x y w h].each do |attribute| %>
<%= f.hidden_field "crop_#{attribute}" %>
<% end %>
<div class="actions">
<%= f.submit "Crop" %>
</div>
<% end %>
I haven't tried to set a callback that stores category_id, but I wonder would it be a good idea? Any help? Thanks!
EDIT - also adding a form partial, but it works fine - just for your curiosity:
<%= form_for(product, hmtl: { multipart: true } ) do |f| %>
...
<div class="field">
<%= f.label :category %>
<%= select_tag(:category_id, options_from_collection_for_select(Category.all, :id, :name, #product.category_id), include_blank: "Select Category") %>
</div>
UPDATE
Logs for these actions:
Started GET "/products/new" for ::1 at 2016-12-15 09:03:31 +0200
Processing by ProductsController#new as HTML
[1m[36mCart Load (0.4ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (2.0ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]]
Rendering products/new.html.erb within layouts/application
[1m[36mCategory Load (0.4ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m
Rendered products/_form.html.erb (6.2ms)
Rendered products/new.html.erb within layouts/application (11.2ms)
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m
[1m[36mLineItem Load (0.5ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]]
Completed 200 OK in 127ms (Views: 113.2ms | ActiveRecord: 3.3ms)
Started POST "/products" for ::1 at 2016-12-15 09:03:40 +0200
Processing by ProductsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"eWZuqL6AqcN8wknjEL115ax9uBnpY4b9eP0o2xN2aPntd61YKyc4Ym1lUgjV1YrXfZbPr57HANXy7Kz5swCtlg==", "product"=>{"title"=>"kj", "description"=>"kj", "image"=>#<ActionDispatch::Http::UploadedFile:0x007fe40ba4abe0 #tempfile=#<Tempfile:/var/folders/dn/zq9x2jkd4856kwhfj5gbz2tc0000gn/T/RackMultipart20161215-3987-1adfacs.png>, #original_filename="Screen Shot 2016-12-05 at 09.14.48.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"product[image]\"; filename=\"Screen Shot 2016-12-05 at 09.14.48.png\"\r\nContent-Type: image/png\r\n">, "price"=>"98", "quantity"=>"98"}, "category_id"=>"1", "commit"=>"Create Product"}
[1m[36mCart Load (0.3ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]]
[1m[35m (0.3ms)[0m [1m[35mBEGIN[0m
[1m[36mCategory Load (0.3ms)[0m [1m[34mSELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT $2[0m [["id", 1], ["LIMIT", 1]]
[1m[35mSQL (1.0ms)[0m [1m[32mINSERT INTO "products" ("title", "description", "price", "quantity", "created_at", "updated_at", "category_id", "user_id", "image") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"[0m [["title", "kj"], ["description", "kj"], ["price", #<BigDecimal:7fe40ccf9110,'0.98E2',9(18)>], ["quantity", 98], ["created_at", 2016-12-15 07:03:41 UTC], ["updated_at", 2016-12-15 07:03:41 UTC], ["category_id", "1"], ["user_id", 1], ["image", "Screen_Shot_2016-12-05_at_09.14.48.png"]]
[1m[35m (3.1ms)[0m [1m[35mCOMMIT[0m
Rendering products/crop.html.erb within layouts/application
Rendered products/crop.html.erb within layouts/application (3.1ms)
[1m[36mCategory Load (0.7ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m
[1m[36mLineItem Load (0.3ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]]
Completed 200 OK in 957ms (Views: 127.8ms | ActiveRecord: 6.7ms)
So I noticed that it renders products/crop.html.erb without a particular ID, so I added in my routes:
resources :products do
get 'crop', on: :member
end
And products_controller create action:
...
respond_to do |format|
if #product.save
if params[:product][:image].present?
format.html { render crop_product_path(#product) }
else
...
Still the same error, that a category must be selected.
And to note - if simply go to edit product (but not from the crop action), category sits there as supposed...
Since form only submits the parameters gathered which are defined in it, you should add a hidden field to set the category_id in crop.html view
<%= image_tag #product.image_url(:large), id: "cropbox" %>
<h4>Preview</h4>
<div style="width:300px; height:200px; overflow:hidden;">
<%= image_tag #product.image.url(:large), :id => "preview" %>
</div>
<%= form_for #product do |f| %>
<% %w[x y w h].each do |attribute| %>
<%= f.hidden_field "crop_#{attribute}" %>
<% end %>
<%= f.hidden_field :category_id %>
<div class="actions">
<%= f.submit "Crop" %>
</div>
<% end %>
Now, when you submit the form, you will receive category_id on server in params[:product][:category_id]