I have new and create actions like this:
def new
#foo = Foo.new
end
def create
#foo = Foo.new(foo_params)
respond_to do |format|
if #foo.save
format.html { redirect_to root_path }
else
format.html { render :new } //**this line I want to send params**
end
end
end
I have a jbuilder file to new action like this:
new.json.jbuilder
json.foo do
json.a "Some important info"
json.b "Some important info"
end
And rails can't read this file after create's validation fails. How to render a view template (like render :new) and send some json data in this view?
I have a js calling like this:
var json_url = window.location.href + ".json";
var foo;
$.ajax({
url: json_url,
dataType: 'json',
async: false,
success: function(data) {
foo = data.foo;
}
});
If you want Rails to render a file, you'll need to remove the call to redirect_to as it will effectively prevent any rendering.
Furthermore, if you don't want the controller to respond to different formats, it's better to skip the call to respond_to, too.
If you just call render action: :new, the view template will have access to all controller instance variables (like #foo):
json.foo do
json.a #foo.a
json.b #foo.b
end
Related
I'm running Rails and trying to set up an autocomplete on my text field. I want to submit to a controller method. If I'm submitting from my form (using the "Submit" button), I'd like to use the "format.html" branch. If I'm submitting using the autocomplete Ajax call, I'd like to use the "format.json" branch ...
def search
if params.has_key?("s")
search = params[:s].strip
#people = Person.where("name ilike ?", "%#{search.upcase}%")
respond_to do |format|
format.html {
if #people.size == 1
redirect_to controller: 'votes', action: 'show', id: #people.first.id
end
}
format.json { #people.map(&:name) }
end
end
end
I set up the autocomplete on my text field like so
$(function() {
return $('#s').autocomplete({
source: function(request, response) {
$.get('/people/search', { s: request.term }, function(data) {
alert(data)
response(data.split('\n'));
});
}
});
});
but what's happening is the value of "data" is an HTML page, as if I were submitting via the format.html method. How do I configure things so that my autocomplete call forces me to render the JSON response from my controller?
Specify .json format in the url like this -
$.get('/people/search.json', { s: request.term }, function(data) {
alert(data)
response(data.split('\n'));
});
To send raw json data In Controller change. Otherwise it will look for template to build json (by default rails will look for search.json.jbuilder)
format.json { render json: {people: #people.pluck(:name)} }
I have implemented my own object creation logic by overriding the create action in a JSONAPI::ResourceController controller.
After successful creation, I want to render the created object representation.
How to render this automatically generated JSON API response, using the jsonapi-resources gem?
Calling the super method does also trigger the default resource creation logic, so this does not work out for me.
class Api::V1::TransactionsController < JSONAPI::ResourceController
def create
#transaction = Transaction.create_from_api_request(request.headers, params)
# render automatic generated JSON API response (object representation)
end
end
You could do something like this:
class UsersController < JSONAPI::ResourceController
def create
user = create_user_from(request_params)
render json: serialize_user(user)
end
def serialize_user(user)
JSONAPI::ResourceSerializer
.new(UserResource)
.serialize_to_hash(UserResource.new(user, nil))
end
end
this way you will get a json response that is compliant with Jsonapi standards
render json: JSON.pretty_generate( JSON.parse #transaction )
def render_json
result =
begin
block_given? ? { success: true, data: yield } : { success: true }
rescue => e
json_error_response(e)
end
render json: result.to_json
end
def json_error_response(e)
Rails.logger.error(e.message)
response = { success: false, errors: e.message }
render json: response.to_json
end
render_json { values }
I am using a bootstrap typeahead plugin. Basically, it expects a json response when you click on one of the items in the dropdown menu. However, when the item is clicked, I want to redirect to a different page; I do not want to respond with json. I don't know how to handle this situation. This is what I have:
def populate_global_search
respond_to do |format|
if params[:name] && params[:name][:value]
model = Model.where(name: params[:name][:value]
else
model = nil
end
if model.present?
format.json { redirect_to model }
else
format.json { head :ok}
end
end
end
The action is triggered from an ajax call:
$(element).bind('typeahead:selected', function(obj, datum, name) {
$.ajax({
url: that.format_url(),
data: {
name : datum
}
}).done(function(data){
...
Since the redirect_to is not a json response, nothing happens when I click on the item. What can I do?
The main problem here, you call the populate_global_search action asynchronously, respond_to block unable to redirect an asynchronously call. To resolve your problem I suggest you render the path to redirect and change the location by window.location:
The javascript code(that's just an assumption):
$(element).bind('typeahead:selected', function(obj, datum, name) {
$.ajax({
url: that.format_url(),
data: {
name : datum
}
}).done(function(data){
// redirect to the desired path
window.location = data.location;
});
The Rails code(also assumption):
def populate_global_search
respond_to do |format|
if params[:name] && params[:name][:value]
# I use find_by, because where return a collection
model = Model.find_by(name: params[:name][:value])
else
model = nil
end
if model.present?
# render a json objects { location: '/some_path/12' }
# with path which you need
format.json { render json: { location: here_is_the_desired_path } }
else
format.json { head :ok }
end
end
end
Bonus, your can reduce your Rails code to, this also should works:
def populate_global_search
model = Model.find_by(name: params[:name].try(:[], :value))
if model.present?
render json: { location: here_is_the_desired_path }
else
head :ok
end
end
Hey everyone I am having an issue setting up my app. It uses the shopify API and essentially what it does is grab some data via a view and sends it to the controller but I am having issues passing it to another method in the controller to use the API to save the data.
Here is my code :
Controller
class BuilderController < ShopifyApp::AuthenticatedController
def index
urlval = request.fullpath
#urlCheck = urlval.split('/').last
end
def show
url = request.fullpath
#urlID = url.split('/').last
#customers = ShopifyAPI::Customer.search(query: "id:"+ #urlID)
#need to get a way to retrieve the ajax call info here to pass into the update
end
def updateCustomer(notes)
#customers.each do |cus|
cus.note = notes
cus.save()
end
end
def new
notes = params[:notes]
updateCustomer(notes)
render json: notes
end
end
View
<button id="test">TEST</button>
<script>
var butt = document.getElementById('test');
butt.addEventListener("click",function(){
$.ajax({
url: "/builder/new",
type: "GET",
data: {
"notes": [
"test",
"test2"
]
},
success: function(data,text,xhr) {
console.log(text);
console.log(xhr);
console.log(data);
alert('successfully');
},
error: function(data,error){
console.log(data);
console.log(error);
alert("help");
}
});
});
</script>
Rather than a fully separate method, have you looked into the
respond_to method? http://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to
You could do (assuming html is the primary request type, change if it isn't):
def index
respond_to do |format|
format.html { actions }
format.json { actions }
end
end
This the method we use to accommodate different request types within the same action. Please let me know if I've misinterpreted your question.
you can use this
update_all(updates) public
Updates all records with details given if
they match a set of conditions supplied, limits and order can also be
supplied. This method constructs a single SQL UPDATE statement and
sends it straight to the database. It does not instantiate the
involved models and it does not trigger Active Record callbacks or
validations.
http://apidock.com/rails/v4.0.2/ActiveRecord/Relation/update_all
def new
notes = params[:notes]
#customer.update_all({note: notes})
respond_to do |format|
format.html {}
format.json { json: #customer.json }
end
end
I am trying to update a model through JSON. Right now I am able to get the put method to execute.
From my browser console, I see this so I believed that my request did go through.
PUT http://localhost:3000/slot_allocations/1 [HTTP/1.1 200 OK 7ms]
However, I am not too sure how I could get Rails to accept the data I want to update and would appreciate it if someone could help me out.
This is my Jquery codes for Ajax request. dataToServer is the data I want to send to update the model.
var url = 'slot_allocations/'+alloc_id;
var dataToServer = {slot_allocation:{timeslot:timeslot, subject:subject,slot_allocation_id:alloc_id-1, group_id:"Group 2", lesson_type:"Tutorial"}}
$.ajax({
type: "PUT",
url: url,
dataType: "json",
data: JSON.stringify(dataToServer) , // message to send goes here
success: function (data)
{
}
});
In my update method in the controller I have the following codes.
def update
#slot_allocation = SlotAllocation.find(params[:id])
respond_to do |format|
if #slot_allocation.update_attributes(params[:slot_allocation])
format.html { redirect_to #slot_allocation, notice: 'Slot allocation was successfully updated.' }
format.json { render :json=>#slot_allocation.as_json }
else
format.html { render action: "edit" }
format.json { render json: #slot_allocation.errors, status: :unprocessable_entity }
format.js { render :js => #slot_allocation.errors, :status => :unprocessable_entity }
end
end
end
And this is my as_json method. I am using it for my send request from the server to the client side but I am not too sure if I could use the same method to send information from the client to the server side.
def as_json(options={})
{
:group_id =>self.group_index,
:lesson_type =>self.lesson_type,
:timeslot =>self.timeslot_id,
:subject =>self.subject_id,
:slot_allocation_id => self.slot_allocation_id
}
end
I would appreciate it if someone could guide me along as I am not too familiar with how I should get Rails to accept the parameters to update the model.
I believe you need to parse the JSON parameters first:
attributes = ActiveSupport::JSON.decode(params[:slot_allocation])
if #slot_allocation.update_attributes(attributes)
...
end
How do I parse JSON with Ruby on Rails?