relate question: Vote_fu and Ajax requests
There seems to be something wrong with my Ajax request.
What I 'm trying to do is on event click vote submit a vote then update page with out refreshing the page.
votes_controller.rb:
def create
#album = Album.find(params[:album_id])
respond_to do |format|
if current_user.vote(#album, params[:vote])
format.js { render :action => "create", :vote => #vote }
format.html { redirect_to([#album.user, #album]) }
#format.xml { render :xml => #album, :status => :created, :location => #album }
else
format.js { render :action => "error" }
format.html { render :action => "new" }
format.xml { render :xml => #vote.errors, :status => :unprocessable_entity }
end
end
end
link | for view album show :
<%= link_to_remote "Vote Up",
:url => user_album_votes_path(album.user, album,
:vote => :true, :format => :js),
:method => :post %>
application.js
jQuery.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
jQuery(document).ready(function() {
$("#votes_.album").bind('click');
})
create.js
page.replace_html "#votes_{#album.id}",
:partial => "album_vote",
:locals => {:album => #album}
This is the following error message which I'm getting:
missing ; before statement
[Break on this error] page.replace_html "#votes_#{#album.id}", ...bum_vote", :locals => {:album => #album}
I'm not sure what is going wrong here I have been following many example from the vote_fu doc's
still having problems.
http://github.com/peteonrails/vote_fu/tree#readme
one amendment made on create.js
there is now another error:
No the error has moved over to the votes_controller
NoMethodError (You have a nil object when you didn't expect it!
<br />
The error occurred while evaluating nil.vote):
app/controllers/votes_controller.rb:53:in `create'
app/controllers/votes_controller.rb:52:in `create'
<br />
Rendered rescues/_trace (128.4ms)
Rendered rescues/_request_and_response (0.4ms)
Rendering rescues/layout (internal_server_error)
These lines are on the create action, which looks perfectly fine!?
How do I get this to work?
Regard
Dan
Try changing the create.js to
page.replace_html "#votes_#{#album.id}", :partial => "album_vote", :locals => {:album => #album}
You might have missed the # for the variable string interpolation.
Solved!
The problem was that I didn't add a before statement to refresh the vote count!
so I did and it worked as well as that, I changing the create.js to create.sj.erb, also I made some small changes to my application.js file. After all that I then added a flash[:note] = you have voted!, then added a function to remove the flash notice after a sec and fadeOut!
For anyone who's interested heres the code:
Application.js
jQuery(document).ready(function() {
$("#vote").bind('click', function(e) {
if (e.target.tagName == "DIV") {
$(this).find(".album_extened").toggle('blind');
}
})
})
create.js.erb
$("#vote").before('<div id="notice"><%= escape_javascript(flash.delete(:notice)) %></div>');
$("#vote_count").html("<%= #album.votes_for - #album.votes_against %>");
$(document).ready(function() {
setTimeout(hideFlashMessages, 1000);
});
function hideFlashMessages() {
$("#vote, #notice").append('').fadeOut(1000);
}
If anyone knows a better why which this can be done please forward!!
A good viewing of [http://railscasts.com/episodes/136-jquery][1]
Reading of [link text][2]
Soon fixed things Thanks Jonathanlink text
[1]: http://railscasts.com/episodes/136-jquery/"Rails Cast ep 136"
[2]: http://www.notgeeklycorrect.com/english/2009/05/18/beginners-guide-to-jquery-ruby-on-rails/"Beginners Guild to jQuery and Rails"
and Thanks Sam for being helpful!!
It seems to me that the current_user in the create method did not get its value set.
How do you set the current_user value? In other plugins, they usually define this as an
instance method or instance variable with accessor.
So maybe changing the create method to the following might help:
def create
#album = Album.find(params[:album_id])
respond_to do |format|
if #current_user.vote(#album, params[:vote])
format.js { render :action => "create", :vote => #vote }
format.html { redirect_to([#album.user, #album]) }
#format.xml { render :xml => #album, :status => :created, :location => #album }
else
format.js { render :action => "error" }
format.html { render :action => "new" }
format.xml { render :xml => #vote.errors, :status => :unprocessable_entity }
end
end
end
You might have missed the # before the current_user.vote
Related
I am trying to create a record in a table direcly when the user clicks on a link.
However it is generating the following error when it tries to load the view.
ActionController::UrlGenerationError in SopHeaders#show
No route matches {:action=>"create", :company_id=>2, :controller=>"sop_detail", :cost=>0.1e2, :cost_sop=>0.103e2, :customer_id=>1, :desc1=>"Printer cable YDP30 - Secura 224 ICEU", :flag_required=>true, :id=>"4", :list_price=>0.0, :opportunity_id=>"9", :product_code=>"01-69Y03293", :quantity=>1, :sophead_id=>4, :unit_price=>0.0}
My view
<%= link_to 'Add to Quote', {:controller => "sop_details",
:action => "create",
:sophead_id => #sop_header.id,
:customer_id => #customer.id,
:company_id => #customer.company_id,
:product_code => stock.product_code,
:unit_price => stock.price,
:quantity => 1,
:cost => stock.cost,
:cost_sop => stock.cost_sop,
:list_price => stock.list_price,
:flag_required => true,
:desc1 => stock.desc1},
:method => "post" %>
My Controller
def new
#sop_detail = SopDetail.new
end
def create
respond_to do |format|
if #sop_detail.save
format.html { redirect_to customer_opportunity_sop_header_path(#customer, #opportunity, #sop_header) }
format.json { render :show, status: :created, location: #sop_header }
else
format.html { render :new }
format.json { render json: #sop_header.errors, status: :unprocessable_entity }
end
end
end
My route table output
customer_opportunity_sop_header_sop_details GET /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details(.:format) sop_details#index
POST /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details(.:format) sop_details#create
new_customer_opportunity_sop_header_sop_detail GET /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details/new(.:format) sop_details#new
edit_customer_opportunity_sop_header_sop_detail GET /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details/:id/edit(.:format) sop_details#edit
customer_opportunity_sop_header_sop_detail GET /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details/:id(.:format) sop_details#show
PATCH /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details/:id(.:format) sop_details#update
PUT /customers/:customer_id/opportunities/:opportunity_id/sop_headers/:sop_header_id/sop_details/:id(.:format) sop_details#update
What am I doing wrong?
Your redirect_to path is not in your routes. You want to go to the customer_opportunity_sop_header_path path while this is not in your routes. I guess you want to navigate to the customer_opportunity_sop_header_sop_details_path.
I want to pass 2 strings to the view after redirecting.
the controller:
def create
#rating = Rating.new(params[:rating])
respond_to do |format|
if #rating.save
format.html { redirect_to #rating, :notice => 'Got It!' ,
:notice_small => 'Your photo has been uploaded. good luck with it\'s coolness rating!' }
format.json { render :json => #rating, :status => :created, :location => #rating }
else
format.html { render :action => "new" }
format.json { render :json => #rating.errors, :status => :unprocessable_entity }
end
end
end
the view:
<p id="notice" class="big_notice"><%= notice %></p>
<% if defined? notice_small %>
<p id="small_notice" class="small_notice"><%= notice_small %></p>
<% end %>
the notice string goes throw but the notice_small does not, why?
Only :notice and :alert are allowed to be set using redirect_to.
If you want something beyond this, use :flash => { :notice_small => '....' } option for redirect_to or set flash[:notice_small] before redirect_to explicitly.
The redirect looks like it should work as far as I can tell. However, to make it available in your view, the action you're redirecting to would have to take params["notice_small"] and put it in an instance variable. Something like
#notice_small = params["notice_small"]
in the actions, then you could do
<% if defined? #notice_small %>
<p id="small_notice" class="small_notice"><%= #notice_small %></p>
<% end %>
So I'm using a form_remote_tag to attempt an ajax form submission, like so:
<% form_remote_tag :update=> 'test', :url=> {:action=>'test_action'} do -%>
It renders with no apparent problem:
<form action="/pages/test_action" method="post" onsubmit="new Ajax.Updater('test', '/pages/test_action', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
The test_action action:
def test_action
if request.xhr?
render :text => 'some text'
else
puts 'nope'
end
end
When I submit the form(via the submit button, nothing weird like the jquery submit() event), no ajax request is made. The xhr check returns false. Help please??
In controller you should respond to specified format, js in your case. For example:
def create
#item = Item.new(params[:item])
respond_to do |format|
if #item.save
flash[:notice] = 'Item was successfully created.'
format.js
format.html { redirect_to(#item) }
format.xml { render :xml => #item, :status => :created, :location => #item }
else
format.html { render :action => "new" }
format.xml { render :xml => #item.errors, :status => :unprocessable_entity }
end
end
end
The best practice for now is to use unobtrusive javascript (UJS). There is no form_remote_tag in rails 3. UJS can be used with rails 2.3 as well.
Basically I am trying to capture the value of the form field before it is saved to the database. Then I intend to use that value in my controller to update a specific field in the database,
using
#taskforms.update_attribute('notes',
$notes)
I need to do this because I know of no other way to update that that does not require the full record to be validated.
The suggestion below to use #taskforms.save(false) is really not what I was looking for optimally. However it could work. However having and issue to get it to work.
What I am currently using (that works with validations)
def myupdate
#taskforms = Taskforms.find(params[:id])
respond_to do |format|
if #taskforms.update_attributes(params[:taskforms])
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
end
However when I try the save(false) it doesn't save and triggers validations anyway
def myupdate
#taskforms = Taskforms.find(params[:id])
if #taskforms.save(false)
#taskforms.update_attribute('edited_at', Time.new )
flash[:notice] = 'Note was successfully updated.'
format.html { redirect_to(:controller => "taskforms", :action => "displayedit", :id => #taskforms.id) }
format.xml { head :ok }
else
format.html { render :action => "displayedit" }
format.xml { render :xml => #taskforms.errors, :status => :unprocessable_entity }
end
end
I have never used Save in the past just the default respond_to do |format| so suspect my code is incorrect.
#taskforms.save(false) will save your model without any validations if that is your main goal.
I've read many posts about this issue but I never got this to work.
My model looks like this:
class Announcement < ActiveRecord::Base
validates_presence_of :title, :description
end
My controller's create method(only its relevant part) looks like this:
def create
respond_to do |format|
if #announcement.save
flash[:notice] = 'Announcement was successfully created.'
format.html { redirect_to(#announcement) }
format.xml { render :xml => #announcement, :status => :created, :location => #announcement }
else
#announcement = Announcement.new
#provinces = Province.all
#types = AnnouncementType.all
#categories = Tag.find_by_sql 'select * from tags where parent_id=0 order by name asc'
#subcategories= ''
format.html { render :action => "new" } #new_announcement_path
format.xml { render :xml => #announcement.errors, :status => :unprocessable_entity }
end
end
end
My form looks like this:
<% form_for(#announcement) do |f| %>
<%= error_messages_for 'announcement' %> <!--I've also treid f.error_messages-->
...
What am I doing wrong?
You are killing your error messages by creating a new announcement in your else statement.
#announcement = Announcement.new # should be removed
When you call #announcement.save it will store the errors in #announcement.errors. By calling #announcement = Announcement.new after this you are going back to a clean slate. So no errors will ever be displayed.