Ajax can not work with Rails3.2.1 - ruby-on-rails

My form
<%= form_tag load_link_path, :remote => true, :html => { :'data-type' => 'html', :id => 'load_link_form' } do %>
<fieldset>
<%= url_field_tag(:url) %>
<div class="validation-error"></div>
<%= submit_tag %>
</fieldset>
<% end %>
My action
def load
format.js
end
My js view(load.js.erb)
alert(0);
When submit the form, alert isn't firing. The console outputs:
Processing by LinksController#load as JS
Parameters: {"utf8"=>"✓", "commit"=>"Save changes", "url"=>"http://www.alfajango.com/blog/rails-3-remote-links-and-forms/", "authenticity_token"=>"KWwfZH+sivCrWdlVBUPM0MBRPHzcDhmbB96ckLQ82Dg="}
Rendered links/load.js.erb (0.4ms)
Completed 200 OK in 2822ms (Views: 9.9ms | ActiveRecord: 0.0ms)

Try adding respond_to at the top of your controller and then wrapping your format.js call in a respond_with block
class LinksController < ApplicationController
respond_to :html, :js
def load
respond_with do |format|
format.js
end
end
end
I'd recommend reading this article, it's the best guide to ajax with rails3 imo.
UPDATE:
I got it working after making a few small changes:
The default method for an ajax call in rails is "GET" so if you want to do a "POST", you need to include this with :data-method=>"post". I also removed the html hash from your form tag and set the data-type to script, see below:
<%= form_tag load_link_path, :remote => true, :id => 'create_link_form', :data => {:type=>"script", :"method"=>"post"} do %>
Also, you need to uncomment the alert from your js.erb file, so change from:
//alert(0);
$('#message').val('ok');
to:
alert(0);
//$('#message').val('ok');
Hope this helps, let me know if it doesn't and i'll push my code to github:)

Related

Creating new object for associated model

So I've been at this a while and have tried a bunch of different methods. Essentially I have an over-arching property model and an associated deed model. From the properties#show view I have it displaying all associated deeds. I have a button in my property view that displays a modal (using AJAX) to create a deed associated to said model. All the steps work (even 'edit' and 'update' using AJAX from the properties view) except when trying to save the new deed I get an error message:
This form contains 1 error. Property must exist
I've tried passing the #properties.id through in different ways and I just can't seem to get it. I'll list all the relevant info I have and if more is needed just let me know.
Property Model
class Property < ApplicationRecord
has_many :deeds, dependent: :destroy
accepts_nested_attributes_for :deeds
end
Deeds Model
class Deed < ApplicationRecord
belongs_to :property
accepts_nested_attributes_for :property
end
Deeds Controller (Included edit and update actions)
def new
#deeds = Deed.new
#deeds.build_property
respond_to do |format|
format.html { render 'new'}
format.js
end
end
def create
#properties = Property.find(params[:deed][:property_id])
#deeds = #properties.deeds.new(deed_params)
if #deeds.save
flash[:success] = "Deed created successfully!"
respond_to do |format|
format.html { redirect_to deeds_path }
format.js
end
else
render 'new'
end
end
def edit
#deeds = Deed.find(params[:id])
respond_to do |format|
format.html { #deeds.save }
format.js
end
end
def update
#deeds = Deed.find(params[:id])
#properties = Property.find(#deeds.property.id)
#deeds.update_attributes(deed_params)
respond_to do |format|
format.html { redirect_to deeds_path }
format.js
end
end
private
def deed_params
params.require(:deed).permit(:property_id, :deed_number, :deed_context, :consideration, :recorded_date, :grantor, :grantee, :trustee)
end
new deeds link from properties#show view
<%= link_to fa_icon("plus", text: "Add Deed"), new_property_deed_path(#properties.id), remote: true, class: "btn btn-primary btn-large btn-ouline pull-right", locals: { property_id: #properties } %>
new.js.erb
$('#deeds-modal').modal("show");
$('#deeds-modal').html('<%= j render partial: "deeds/deeds_modal", locals: { property_id: #properties } %>');
_deeds_modal.html.erb partial Form
<div class="modal-body">
<%= bootstrap_form_for(#deeds, layout: :horizontal, remote: true) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.hidden_field :property_id, value: property_id %>
<%= f.text_field :deed_number, class: 'form-control' %>
<%= f.text_field :deed_context, class: 'form-control' %>
<%= f.text_field :consideration, class: 'form-control' %>
<%= f.text_field :recorded_date, class: 'form-control' %>
<%= f.text_field :grantor, class: 'form-control' %>
<%= f.text_field :grantee, class: 'form-control' %>
<%= f.text_field :trustee, class: 'form-control' %>
<%= f.form_group do %>
<%= f.submit "Save", class: "btn btn-primary" %>
<% end %>
<% end %>
</div>
server response upon deeds_modal form POST
Started GET "/properties/99/deeds/new" for 127.0.0.1 at 2017-05-30
23:24:48 -0400
Processing by DeedsController#new as JS
Parameters: {"property_id"=>"99"}
Rendering deeds/new.js.erb
Rendered shared/_error_messages.html.erb (0.4ms)
Rendered deeds/_deeds_modal.html.erb (5.6ms)
Rendered deeds/new.js.erb (7.3ms)
Completed 200 OK in 14ms (Views: 10.6ms | ActiveRecord: 0.0ms)
Started POST "/deeds" for 127.0.0.1 at 2017-05-30 23:24:55 -0400
Processing by DeedsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"eaj9K...==", "deed"=>{"property_id"=>"", "deed_number"=>"69696969", "deed_context"=>"Bagel slaps", "consideration"=>"Considered", "recorded_date"=>"2017-05-31", "grantor"=>"", "grantee"=>"NipLips", "trustee"=>""}, "commit"=>"Save"}
(0.1ms) BEGIN
(0.1ms) ROLLBACK
Rendering deeds/new.js.erb
Rendered shared/_error_messages.html.erb (0.7ms)
Rendered deeds/_deeds_modal.html.erb (12.1ms)
Rendered deeds/new.js.erb (20.4ms)
Completed 200 OK in 32ms (Views: 30.6ms | ActiveRecord: 0.2ms)
So as you can see I've tried to pass through a local variable from the new link -> new.js.erb -> deeds modal form but I can't seem to pull the property_id into the new deeds object.
Is this even the correct approach for what I'm trying to do or am I just missing something? Hope this wasn't too long of a read and that I provided enough info... lol.
*Upon writing this post I clicked through some of the 'similar questions' on SO, which is where I got the #properties = Property.find(params[:deed][:property_id]) line from but I still get ActiveRecord::RecordNotFound (Couldn't find Property with 'id'=): upon submission. Also, thank you to anyone who takes the time to read this.
rails routes Update (only included relevant routes for brevity)
deeds GET /deeds(.:format) deeds#index
POST /deeds(.:format) deeds#create
new_deed GET /deeds/new(.:format) deeds#new
edit_deed GET /deeds/:id/edit(.:format) deeds#edit
deed GET /deeds/:id(.:format) deeds#show
PATCH /deeds/:id(.:format) deeds#update
PUT /deeds/:id(.:format) deeds#update
DELETE /deeds/:id(.:format) deeds#destroy
...
property_deeds GET /properties/:property_id/deeds(.:format) deeds#index
POST /properties/:property_id/deeds(.:format) deeds#create
new_property_deed GET /properties/:property_id/deeds/new(.:format) deeds#new
edit_property_deed GET /properties/:property_id/deeds/:id/edit(.:format) deeds#edit
property_deed GET /properties/:property_id/deeds/:id(.:format) deeds#show
PATCH /properties/:property_id/deeds/:id(.:format) deeds#update
PUT /properties/:property_id/deeds/:id(.:format) deeds#update
DELETE /properties/:property_id/deeds/:id(.:format) deeds#destroy
This should be you new action
def new
#deeds = Deed.new
#deeds.build_property
#properties = Property.find_by_id(params[:property_id]) # add this line
respond_to do |format|
format.html { render 'new'}
format.js
end
end
Update:
If you are not using the associated property anywhere else, you don't need to pass the locals and I don't suggest hidden_field as it can be easily modified, alternately you can do..
def new
#deeds = Property.find_by_id(params[:property_id]).deeds.new # add this line
#deeds.build_property
respond_to do |format|
format.html { render 'new'}
format.js
end
end
As the error says Property must exist, so, your intention is to print the property_id for a new record, but for some reason that's not happening.
As that value goes from your form_for directly to create a new "deed", then in must be setted on it, you do it, but you don't check if it's printing something or not, and it get's you a nil value that's not allowed because of the relationship between Deeds and Properties.
When you send the form, you can see the value is empty:
"deed"=>{"property_id"=>""}
How do you define which property_id must a new record have? You can create a variable within your new method and set an object to print within your form_for, it'll give you a value to proceed with a new record.
When you make a request to the new method you pass through the params the value for property_id:
Processing by DeedsController#new as JS
Parameters: {"property_id"=>"99"}
So I suppose you could use it instead setting a local variable which hasn't been initialized, maybe you can try with:
<%= f.hidden_field :property_id, value: params[:property_id] %>

form_for with validation does not called "create" action correctly

I had a form that I want user to answer every question, so I add a model-level validation.
I supposed if it pass validation, it should redirect to another page call "scenario" (I haven't finish it's view so it should show template missing). If it does not pass validation, it should render once again to the new page, remains the information already filled in, and show validation error.
But no matter I filled out those fields or not, when I click submit button, it always show me the index page instead of "new" or "scenario"(which should be template missing). It seems ignore what I have wrote in the action "create", and "create" is never been called.
I use rails c and insert a new record to test validation. It does work well, so I guess there is no problem for my model and validation.
I also try to make form_for redirect to "scenario" directly, to make sure it work well for form_for, and it does show templete missing to me, so there might be some problem for "create" itself. I really don't know what's going wrong.
<%= form_for #subject, :url => { :controller => 'appstores', :action => 'scenario' } do |f| %>
There is a similar question: rails form_for never invokes the create controller action to use redirect_to.
I had try to use "respond_with", not work. And also check my controller is named as appstroes_controller.rb with resources :appstores in routes.rb.
I use rails 4.2.4, ruby 2.0.0, and bootstrap 3, don't know whether the version cause those problem or not.
Any help would be appreciated, thanks!
app/controller/appstores_controller.rb
class AppstoresController < ApplicationController
def index
end
def new
#subject = Subjectinfo.new
end
def create
#subject = Subjectinfo.new(params[:subjectinfo])
if #subject.save
redirect_to :action => "scenario"
else # if not pass DB validation
render :action => :new
end
end
def scenario
end
end
app/view/appstores/new.html.erb
<%= form_for #subject, :url => { :controller => 'appstores', :action => 'create' } do |f| %>
<form class="form-horizontal">
<div class="form-group">
<%= f.label :username, "User Name:", :class=>"control-label", :for=>"username" %>
<% if #subject.errors[:username].presence %>
<span class="model-error"><%= #subject.errors[:username].join(", ") %></span>
<% end %>
<%= f.text_field :username, :autocomplete=>"off", :placeholder=>"User Name", :class=>"form-control", :id=>"username" %>
</div>
<div class="form-group">
<%= f.label :mobile_user, "Are you a mobile device user?", :class=>"control-label", :for=>"mobile_user" %>
<% if #subject.errors[:mobile_user].presence %>
<span class="model-error"><%= #subject.errors[:mobile_user].join(", ") %></span>
<% end %>
<div class="radio radio-primary">
<%= f.radio_button :mobile_user, "1", :id=>"mobile_user_1" %>
<%= f.label :mobile_user, "Yes", :class=>"control-label", :for=>"mobile_user_1" %>
</div>
<div class="radio radio-primary">
<%= f.radio_button :mobile_user, "0", :id=>"mobile_user_0" %>
<%= f.label :mobile_user, "No", :class=>"control-label", :for=>"mobile_user_0" %>
</div>
</div>
<div class="text-center">
<%= f.submit "NEXT", :class => "btn btn-default btn-outline btn-lg" %>
</div>
</form>
<% end %>
app/modle/subjectinfo.rb
(to support "attr_accessible" for rails 4, I had put "gem 'protected_attributes'" in my Gemfile)
class Subjectinfo < ActiveRecord::Base
validates_presence_of :username, :mobile_user
attr_accessible :username, :mobile_user
end
config/routes.rb
AppStore::Application.routes.draw do
match ':controller(/:action(/:id(.:format)))', :via => :all
root :to => "appstores#index"
resources :appstores
get "appstores/scenario"=>"appstores#scenario"
end
rake routes
Prefix Verb URI Pattern Controller#Action
/:controller(/:action(/:id(.:format))) :controller#:action
root GET / appstores#index
appstores GET /appstores(.:format) appstores#index
POST /appstores(.:format) appstores#create
new_appstore GET /appstores/new(.:format) appstores#new
edit_appstore GET /appstores/:id/edit(.:format) appstores#edit
appstore GET /appstores/:id(.:format) appstores#show
PATCH /appstores/:id(.:format) appstores#update
PUT /appstores/:id(.:format) appstores#update
DELETE /appstores/:id(.:format) appstores#destroy
appstores_rfscenario GET /appstores/rfscenario(.:format) appstores#rfscenario
Btw, here is what I saw form terminal, this is when I filled in all the fields.
Started POST "/appstores" for 127.0.0.1 at 2015-11-03 22:25:54 +0800
Processing by AppstoresController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7WV4Iw/0uHNSnuXpr8qa39oFEF9gZfKm8EyHGQna0o0=", "subjectinfo"=>{"username"=>"a1", "mobile_user"=>"1"}, "commit"=>"NEXT"}
Rendered appstores/index.html.erb within layouts/application (12.6ms)
Completed 200 OK in 91ms (Views: 88.0ms | ActiveRecord: 0.0ms)
Here is when I leave them blank, but no matter it is blank or not, it always render to index......
Started POST "/appstores" for 127.0.0.1 at 2015-11-03 22:25:54 +0800
Processing by AppstoresController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7WV4Iw/0uHNSnfuXpr8qa39oFEF9gZfKm8EyHGQna0o0=", "subjectinfo"=>{"esearch"=>""}, "commit"=>"NEXT"}
Rendered appstores/index.html.erb within layouts/application (12.6ms)
Completed 200 OK in 91ms (Views: 88.0ms | ActiveRecord: 0.0ms)
Remove the line match ':controller(/:action(/:id(.:format)))', :via => :all from your routes.rb file and never use it anymore. This pattern matches any route and it is on the first position, other routes in your file don't have a chance at all because of that.

Rails create method: hidden field tag submitting but not working & sessions param not working

I have a the following form I'm trying to submit (from the show method view):
<%= form_for(Photo.new, :remote => true, html: {multipart: :true}) do |f| %>
<%= f.label :title, 'Title' %>
<%= f.text_field :title %>
<%= f.label :image, 'Choose Image' %>
<%= f.file_field :image %>
<%= f.hidden_field :item_id, :value => #item.id %>
<%= f.submit 'Add' %>
<% end %>
And I'm trying to use the following create method:
def show
#item = Item.find(params[:id])
end
def create
#item = Item.find(params[:item_id])
#photo = Photo.new(photo_params)
redirect_to edit_photos_url, notice: 'Photo uploaded' if #photo.save
end
This is what the logs generate:
Started POST "/photos" for ::1 at 2015-07-03 21:17:10 -0400
Processing by PhotosController#create as HTML
Parameters: {"utf8"=>"✓", "photo"=>{"title"=>"sdb", "image"=># <ActionDispatch::Http::UploadedFile:0x007fe301a2ebf8 #tempfile=#<Tempfile:/var/folders/d8/hx2wgfwx7m77c6mjwx2pffcc0000gq/T/RackMultipart20150703-35083-rt86ai.png>, #original_filename="Screen Shot 2015-06-28 at 9.23.31 PM.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"photo[image]\"; filename=\"Screen Shot 2015-06-28 at 9.23.31 PM.png\"\r\nContent-Type: image/png\r\n">, "item_id"=>"27"}, "commit"=>"Add"}
Can't verify CSRF token authenticity
Completed 404 Not Found in 1ms
ActiveRecord::RecordNotFound (Couldn't find Item without an ID):
app/controllers/photos_controller.rb:13:in `create'
The item_id seems to be submitted, yet it doesn't work ?
I've tried also implementing sessions, which would be more ideal. I've done the following in the create method of the items controller:
remember_item #item
Calling the method in the helper:
def remember_item(item)
cookies.permanent.signed[:item_id] = item.id
session[:item_id] = item.id
end
I've checked the session variables, and the :item_id did get passed correctly in the session. I've tried the following:
def create
#item = Item.find(session[:item_id])
#photo = #item.photos.build(photo_params)
redirect_to edit_photos_url, notice: 'Photo uploaded' if #photo.save
end
And this also doesn't work, giving the following error:
Couldn't find Item without an ID
I'd really like to get the latter to work. Suggestions?
The item_id is included in the photo params
#item = Item.find params[:photo][:item_id]
Should give you what you want.
If you look closely, what you are submitting is actually
params
=> {photo: {item_id: 1, **other_attrs}}
params[:item_id]
=> nil
params[:photo][:item_id]
=> 1
That is because item_id is in your form as a helper and the form helper thinks it is a property of photo.

where does render :partial html end up

I have a view with an ajax form:
<%= form_tag( {:action => 'some_action'}, {:remote => true}) do %>
...
<%= submit_tag "Submit" %>
<% end %>
Now, in the target action, I want to display a partial
def some_action
# some logic
render :partial => "some_partial"
end
The partial is just html. _some_partial.html.erb could be
<br>Hi, this is the partial</br>
When I submit the form, I see the html response packet is received in the browser (with firebug's net logs), but the html doesn't show up anywhere. Where should the html be? How to render a partial html view from an action?
you are rendering a partial but not specifying where to render it.
in rails 2 you could do it with:
def some_action
# some logic
render :update do |page|
page.replace_html 'some_div_id', :partial => 'some_partial'
end
end
but in rails 3, above code is no longer valid.
see Unobtrusive Javascript
create a file named some_action.js.erb and write the code in it:
// update div with id some_div_id
$("#some_div_id").html("<%= escape_javascript(render :partial => 'some_partial') %>");
in controller
def some_action
# some logic
respond_to do |format|
format.js
end
end
I figured out how to send and display html. From theReq, just add :remote => true, "data-type" => "html" to the form and then in the javascript of the page, capture the returned html on ajaxSuccess to display it:
$('form#whatever').on('ajaxSuccess', function (event, data, status, xhr) {
$('div#target').html(data);
}
)

Ruby On Rails 3 submit form AJAX update results in div

I am stuck; I did a search and I can't find a pointer on how to get this project to work. I have a form on my index.html.erb as:
<html> <head>
<title>Ajax List Demo</title> <h1>Listing posts</h1>
<%= javascript_include_tag "prototype" %> </head> <body>
<h3>Add to list using Ajax</h3>
<% form_tag ( :remote=>true, :update => 'my_list', :action => :list , :method=>:post, :format =>:xml ) do %>
Enter the url:
<%= text_field_tag 'url' ,'', :size => 80 %>
<%= submit_tag "Find" %>
<% end %>
<div id="my_list"><%= render :partial => 'profiles/list' %></div> </body> </html>
Now I have a div with this called my_list. When I submit the form I want my partial _list.html.erb (inside profiles dir, tried home dir too) to update with the results of list.
My home controller has this method:
def list
puts "here!!!!"
reader = Reader.new
#profiles = reader.processURL(params[:url])
render :partial=>'profiles/list', :locals => { :profiles => #profiles}
end
I end up getting this error:
ActionView::MissingTemplate (Missing partial profiles/list with {:locale=>[:en, :en], :handlers=>[:rjs, :builder, :rhtml, :rxml, :
erb], :formats=>[:xml]} in view paths "C:/Users/....tree/app/views"):
app/controllers/home_controller.rb:22:in `list'
Rendered C:/Ruby187/lib/ruby/gems/1.8/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/missing_template.erb
within rescues/layout (1.0ms)
Could anyone help me or send me in the right direction to understand how to update a div rendering via Rails on form submit? Thanks again.
First of all I am getting ajax to render(#homepages) in index.html.erb via index.js.erb OK, but my search to update #homepages is not working.
In your javascript_include_tag you missed out rails.js which I think handles the ajax request. javascript_include_tag :defaults would have done all that for you plus some others that you do not need. Providing you are not using jquery you need prototype and rails.js as a minimum.
I do not think the format of this form_tag is correct:
<% form_tag (:remote=>true, :update => 'my_list', :action => :list , :method=>:post, :format =>:xml) do %>
The first value after the "(" should be the item_path, then the conditions :action => :list.
:method => post should take you to the create or new action.
:update => 'my_list' would be done in the list.js.erb using javascript (prototype)
The code for jquery and prototype is similar, but slightly different (see Railscast 205)
Why format xml in the form_tag, put it in the controller "list" mine is:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #homepages }
format.js
end
Don't sure if you can get away with 'url' should not it be :url you might be able to use either.
When I was getting the missing template it was because it was looking for a search.html.erb file. In your case it is looking for a list.html.erb.

Resources