rails select query creating alias for attribute name - ruby-on-rails

With the goal of creating a JSON string, the requirement is to use an existing attribute and assign it, in the JSON output, with the attribute name id.
#valids = Destination.limit(10).select(:name, :long_name, :other_code).as_json(except: :id)
except: :id is being invoked to avoid confusion, as other_code attribute is intended to be the id in the generated JSON.
this will then be transformed into valid JSON via
#valids.to_json
how can other_code be output as id ?

You can do this like that with a simple string instead of symbols.
Destination
.limit(10)
.select('name, long_name, other_code as id')
.as_json

Honestly am new to Ruby on rails but very experience with json and frontend application responses
You can try this. if it work, you can now try it with your database responses. Ensure that column id exist in that your database
def your_definition_here
respond_to do |format|
#valids='999'
format.json do
render json: {id: #valids}.to_json
#render json: {id: #valids.id}.to_json
end
end
end

Related

Rails API get params to a custom method

Am trying to filter some data from database but its not getting params. This is my method:
def user_orders
orders = Order.select { | item | item[:user_id] == params[:id] }
if orders
render json: orders, status: :ok
else
render json: {error: "No orders available"}
end
end
This is the custom routing
get "/orders/user/:id", to: "orders#user_orders"
and the response is an empty array. However if I pass in a number in the method like so:
orders = Order.select { | item | item[:user_id] == 27 }
I get back the filtered array as expected. How can I pass in a dynamic ID from the routing?
EDIT: if your parameters look like this:
Parameters: { … "order"=>{…"user_id"=>27}}
… then you need to access the user_id as params[:order][:user_id].
Otherwise your conditional is comparing nil to 27, which will return false, and so nothing is ever selected.
If you’re querying an activerecord model, I also recommend that you use Order.where(item: {user_id: params[:id]}) to find your list of orders, so that and rails can cast to the right type as well.
What does the line in the rails log say? It should start with GET /user/orders and it should list what parameters have actually been received. Alternatively you can use puts to check the content of params.

How to create Post request to Rails API using Postman?

I am new to Postman. I have a Rails server running on the background. I am trying to mock a POST request, but it is not being accepted.
Let's say the model is called manufacturer_organization.rb. Inside, it requires 3 parameters: organization_id (uuid data type), manufacturer_id (integer data type), and account_number (string data type). manufacturer_organization belongs_to organization and it also belongs_to :manufacturer (vice versa; manufacturer and organization has_many manufacturer_organization)
Inside manufacturer_organizations_controller.rb, I have a create method:
def create
#manufacturer_organization = ManufacturerOrganization.new(manufacturer_organization_params)
if #manufacturer_organization.save
puts "success!"
render json: #manufacturer_organization
else
puts "Sorry, something went wrong"
end
end
I can confirm that I have sufficient authorization; when I perform a GET request I got the right JSON response. I am using rails serializer and I have setup serializer for this model as well. Route is also setup using resources :manufacturer_organizations. My gut feeling says the way I am using postman is wrong.
Here is the screenshot of Postman app. I have the right address on address bar, and I am performing a POST request. I have the three params under key-value.
After I Send it, under my Rails Server log I see:
Started POST "/manufacturer_organizations" for 127.0.0.1 at 2017-04-13 16:56:44 -0700
Processing by ManufacturerOrganizationsController#create as */*
Parameters: {"organization_id"=>"fb20ddc9-a3ee-47c3-bdd2-f710541-ff89c", "manufacturer_id"=>"1", "account_number"=>"A rand
om account number test"}
...
  (0.4ms)  BEGIN
   (0.3ms)  ROLLBACK
Sorry, something went wrong
I can do ManufacturerOrganization.new(organization_id: Organization.last.id, manufacturer_id: Manufacturer.last.id, and account_number: "random test account number") just fine inside rails console.
How can I submit a POST request from postman to add a new manufacturer_organization?
Edit:
def manufacturer_organization_params
api_params.permit(:organization_id, :manufacturer_id, :account_number)
end
whereas inside application_controller.rb
def api_params
#api_params ||= ActionController::Parameters.new(ActiveModelSerializers::Deserialization.jsonapi_parse(params))
end
Edit2:
I added error.full_messages and this is what I got:
Manufacturer can't be blank
Organization can't be blank
Account number can't be blank
Why are they blank?
You can pass the data using params or within the body request.
The best way to do this is using the body, because you can send files and the request becomes more clean without the params.
To send data in the body, you must pass the model name and attribute in the "key" field, and the value in the "value" field, like this:
I don't understand what you do to your params. There is a reason the ActiveModelSerializers::Deserialization is namespaced in the "Model" namespace. It shouldn't be used to serialize or de-serialize internet params, but instead it's for serializing/de-serializing model instances.
If parameters arrive in the correct format ActionController::Base from which AplicationController and thus ManufacturerOrganizationsController inherit will de-serialize them for you. The Rails query parameter format looks as follows:
name=something #=> params[:name] = 'something'
names[]=something1&names[]=something2 #=> params[:names] = ['something1', 'something2']
instance[id]=1&instance[name]=foo #=> params[:instance] = {id: '1', name: 'foo'}
This can also be stacked and is used for nested resources by Rails. Example:
instance[title]=some&instance[nested][name]=thing&instance[nested][ids][]=1&instance[nested][ids][]=2
#=> params[:instance] = {title: 'some', nested: {name: 'thing', ids: ['1', '2']}}
Having said that let's get to your example. First of al let us throw away those manual building of params and stick to the convention:
class ManufacturerOrganizationsController
# ...
private
def manufacturer_organization_params
# arriving params should look like this:
#
#=> params = {
# manufacturer_organization: {
# organization_id: 'fb20ddc9-a3ee-47c3-bdd2-f710541-ff89c',
# organization_id: '1',
# account_number: 'A random account number test'
# }
# }
#
# The method #require raises an exception if the provided key
# is not present or has a blank value (with exception of false).
# If the key is found and has a value present than that value is
# returned.
#
params.require(:manufacturer_organization)
.permit(:organization_id, :manufacturer_id, :account_number)
end
end
With that out of the way let's send the correct formatted params:
+--------------------------------------------+---------------------------------------+
| Key | Value |
|--------------------------------------------|---------------------------------------|
| manufacturer_organization[organization_id] | fb20ddc9-a3ee-47c3-bdd2-f710541-ff89c |
| manufacturer_organization[manufacturer_id] | 1 |
| manufacturer_organization[account_number] | A random account number test |
+--------------------------------------------+---------------------------------------+
Those 2 things combined should let you create your resource successfully.
The key thing you should take from this is that params is not a string containing al the params that should be de-serialized. It already should be de-serialized, if it's not than you might have send your parameters wrong.
Ruby on Rails and Postman - Post request.
Hello, this is an example that I developed with Postman and Rails API.
Postman.
I can't add images but this what you have to add in postman Key = Value
Change to Post Request and send.
book[name] = 'Harry Potter'
book[author] = J.K. Rowling
Ruby on Rails 7.
Rails maintains the same code.
def create
#book = Book.new(book_params)
if #book.save
render json: #book, status: :created, location: api_v1_books_url(#book)
else
render json: #book.errors, status: :unprocessable_entity
end
end
def book_params
debugger
params.require(:book).permit(:name, :author, :price)
end
I hope this helps.

How to create temporary attribute & use that in json reponse in rails active record

I am new to ROR.
I am having a controller where i am getting the search results in available_users variable..
availble_users //some active record result with id,name & address
available_users.each do |userstatus|
userstatus.class_eval do
attr_accessor :is_friend
end
if current_user.invitations.find_by(:friend_id => userstatus.id) //invitation is another table
userstatus.is_friend = "true"
else
userstatus.is_friend = "false"
end
end
render json: available_users
but when i am getting the response on ajax request it is serving the same array without including is_friend column.
here is my json response.
id: 2
name: abc
address:
please can anyone figure me out why it is not appending this temporary attribute.
Thanks.
what you have will work if you pass the methods option to_json
render json: available_users.to_json(:methods => :is_friend)
Or you could do this
available_users.each do |userstatus|
if current_user.invitations.find_by(:friend_id => userstatus.id) //invitation is another table
userstatus["is_friend"] = "true"
else
userstatus["is_friend"] = "false"
end
end
render json: available_users
[]= is an alias for write_attribute

Sending a query string to rails respond_to

I am rather new to ruby and rails development.
for the past little while, I have been trying to figure out how I can pass params/query string to a rails respond_to block. I am focusing on the json response.
Say I have the following
def index
#employees = Employee.all
respond_to do |format|
format.html
format.json { render json: #employees }
end
end
and I am looking to only get a json response containing employees who have an id that is greater than 500. What would be the best way to go about this.
I have been trying to make the json request using jQuery.ajax() and I know you can pass data to the server that is formatted to a query, but not sure how to make it work.
The above example is only hypothetical. I am only looking for a way to be able to use a query sting when wanting a json response.
Thanks for the help!
Whatever parameters are sent with the request (in the query string) should be available in your controller (check the params variable). Here's one way to get the Employees with id's at & above 500:
Replace
#employees = Employee.all
with
#employees = Employee.find(:all, conditions: ["id >= ?", 500])
Please note that you don't need to pass anything besides the format to that respond_to block.

Array of ActiveRecords to JSON

I am aware that ActiveRecord provides a to_json method which allows fields to be filtered out of the JSON output using :only and :except.
At present I am using the following to format an array from a find as JSON:
#customers = Customer.find(:all)
...
format.js { render :json => #customers}
How would I be able to select the fields to be output in the objects in the array? Is there a shortcut or do I need to do this by hand?
Cheers,
Adam
I think you answered your own question. With Rails 2.3.x you could use the following:
#customers = Customer.all #Shortcut for to Customer.find(:all)
respond_to do |format|
format.js { render :json => #customers.to_json(:only=>[:column_one, :column_two]}
end
You can overwrite the to_json method of the model class if you want to globally apply the change for the model.
For example, to exclude null values from the rendered JSON you could overwrite the original ActiveRecord method to_json
def to_json(options)
hash = Serializer.new(self, options).serializable_record
hash = { self.class.model_name => hash } if include_root_in_json
ActiveSupport::JSON.encode(hash)
end
with this in your model class:
def to_json(options)
hash = Serializer.new(self, options).serializable_record.reject {|key, value| value.nil? }
hash = { self.class.model_name => hash } if include_root_in_json
ActiveSupport::JSON.encode(hash)
end
If you peep into the ActionController::Base class, you'll see that it calls to_json on your collection immediately (no extra options used), so you've got to have it already prepared. So if in your action you don't use the attributes that are not rendered to json, you can replace your find with
#customers = Customer.find(:all, :select => ["id", ...])
to select only the ones that you need.

Resources