Rails API get params to a custom method - ruby-on-rails

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.

Related

Problem with selecting elements with the same params

What i do wrong? I want to return every products which pass condition:
def show
products = Product.select{|x| x[:category_id] == params[:id]}
render json: products
end
When i write
def show
products = Product.select{|x| x[:category_id] == 1}
render json: products
end
it works why the first example doesn't work?
I am pretty sure that there is mismatch in data type.
1=='1' #will be always false
1==1 #will be true
'1'=='1' #will be true as well
And also check for nil value from params[:id]
Please make sure to change as follows
def show
products = Product.select{|x| x.category_id == params[:id].to_i}
render json: products
end
OR
The best solution as suggested by #Eyeslandic is to use .where as it will not check for mismatch in data type. And also you don't have to take care of nil value from params[:id].
You should really be using a where to stop sql from loading all your products.
#products = Product.where('category_is = ?', params[:id])
The being said, if you are sticking to rails restful conventions, the fact you have a param called :id that is the category_id suggests you are on the category controller. So maybe consider changing your logic to:
#category = Category.includes(:products).find(params[:id])
you can then access products via
#category.products
or if your not interested in the category too much maybe
#products = Category.includes(:products).find(params[:id])&.products

rails select query creating alias for attribute name

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

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 get an array of objects after several ajax calls

In a project, I implement checkbox filters via ajax. In my controller I have an action:
def casinos_filters
providers_from_categories = Provider.joins(:categories).where('categories.id = ?', params[:category_id])
providers = Casino.joins(:providers).where('providers.id = ?', params[:provider_id])
providers_from_categories.each do |provider|
#filtered_casinos = provider.casinos
end
casinos_list = []
casinos_list << #filtered_casinos if params[:category_id]
casinos_list << providers if params[:provider_id]
render json: { casinos: casinos_list.uniq }, status: 200
end
As a result, I want the array casinos_list include the casinos' objects. Clicking on a category checkbox, I get the json. But when I click the next category checkbox, the json doesn't have previous results. I think it's due to the initializing an empty array in the action. Is there any way to initialize the array only once, not on every ajax call? Thanks.
HTTP requests are stateless. You either need to store them in client side (as Javascript models/collections) or on the server side to be able to collect them together.

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

Resources