RAILS API Endpoint - ruby-on-rails

I am a .NET developer and need to work on a API built in Ruby. Following is the API Code. Can anybody help me in getting the endpoint to it.
class Api::SessionsController < ApplicationController
respond_to :json
skip_before_filter :verify_authenticity_token
before_filter :protect_with_api_key
def update
status = true
participant_ids = []
unless params[:participants].blank?
params[:participants].each do |participant_data|
participant = Participant.where(participant_id: participant_data['participant_id']).first
unless participant.present?
status = false
participant_ids << participant_data['participant_id']
else
activity_records = participant_data['cumulative_time']['activity_records']
participant_data['cumulative_time']['activity_records'] = [] if activity_records.nil?
participant.participant_sessions.new(participant_data['cumulative_time'])
participant.save!
end
end
end
if status
render :json => {status: "OK"}
else
render :json => {error: "No participant with id # {participant_ids.join(',')}"}, :status => 422
end
end
end
I have tried to work with following way /api/sessions/
Pass the required key
passing the
participant parameter with PUT Request like below
{"participants":[{"first_name":"Demo", "last_name":"User", "email":"demouser#demouser.com", "password":"RubyNewBie","postal_code":"160055", "coordinator_name":"RubyNewBie", "coordinator_email":"info#RubyNewBie", "coordinator_phone":""}]}
Please guide me.
Thanks and Regards

By default, update action routes to /api/sessions/:id, so you should make query to that url. Also make sure that you have your route for session set up in routes.rb
Edit:
namespace :api do
resources :participants do
resources :sessions
end
end
If it looks like that, then you're using nested routing. Check:
http://guides.rubyonrails.org/routing.html#nested-resources
You'll have to use the url /api/participants/:participant_id/sessions/:session_id under that setting.

Related

HTTParty not sending object parameters in POST request

I'm building a basic admin rails application for a Service I use to make creating new users more efficient. Right now, I'm doing it manually, within the application, and it has some tedious steps that I'd like to automate.
The service considers users as "Members"
So I've created a Members scaffold in my rails project which has the same parameters as members do in the Service.
Instead of entering some data in the Service application, I want to do that in my app. So I have a form with several parameters that create a Member and save those parameters: :usname :usemail :usstudio_uid
Next, I want to POST to the Service API with the initial fields that were entered to create an "invitation" for the new member.
I'm trying to do that by calling on a HTTParty function in my Member's Show view.
My form is saving the parameters correctly, I'm connecting to the Service API via HTTParty and creating an invitation OK, but the Member parameters I want to send aren't populating. Instead it's turning what I thought was a reference to the parameter in plain text.
Snippet of that function:
:body => {"callback_url" => "https://foo.com/#invitations",
"consumer_key" => "my consumer_key", "email" => :usemail,
I want :usemail to reference the parameter of the Member being referenced in the show page(i.e. cliff#foo.com). Instead, as you'll see below, the Service API instead thinks the parameter is a string, returning "usemail" as the email parameter, not that of the Member object I want to reference.
I'm pretty new to rails and coding, so it's probably an obvious answer, but I spent a good 6 hours yesterday trying to figure it out. Help! :)
members.rb model:
class Member < ActiveRecord::Base
end
members_controller rb:
Class MembersController < ApplicationController
before_action :set_member, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#members = Member.all
respond_with(#members)
end
def show
#member = Member.find(params[:id])
end
def new
#member = Member.new
respond_with(#member)
end
def edit
respond_with(#member)
#member.save
end
def create
#member = Member.new(member_params)
#member.save
respond_with(#member)
end
def update
#member.update(member_params)
respond_with(#member)
end
def destroy
#member.destroy
respond_with(#member)
end
private
def set_member
#member = Member.find(params[:id])
end
def member_params
params.require(:member).permit(:usname, :usemail, :usphone, :uspassword, :usconfirm_password, :usinvitation_uid, :usstudio_uid, :uscallback_url, :usmember_uid, :ususername, :usaccess_token)
end
end
In my members_helper.rb:
def getinvitation(member)
result = HTTParty.post "https://foo.com/api/v2/studios/studio_uid/invitations", :body => {"callback_url" => "https://foo.com/#invitations",
"consumer_key" => "my consumer_key", "email" => :usemail,
"name" => :usname, "studio_uid" => :usstudio_uid
}.to_json, :headers => {'X-Auth-Token' => "my token"}
JSON.parse(result.body)
x = ActiveSupport::JSON.decode(result.body)
end
I call on the function in the member's show path:
views/members/show.html.erb
<%= getinvitation(#member) %>
Here is the response I get:
{"uid"=>"29ad0740f4aa47d788bb2a34e9ab7d78", "studio_uid"=>"ORfspJitFbVG",
"date_sent"=>"Sun Feb 1 16:49:21 2015", callback_url"=>"https://app.ustudio.com/#invitations?
invitation_uid=29ad0740f4aa47d788bb2a34e9ab7d78&studio_uid=ORfspJitFbVG",
"consumer_key"=>"my consumer_key", "email"=>"usemail", "name"=>"usname"}
Basically, this is what I was looking for
"email" => member.usemail not :usemail or "usemail"

Finding a Model with Params other than ID

I'm using Rails 4 with strong parameters to try to find a user by a parameter called "provider_id".
The hope is that I'll be able to make a call with my API to a URL such as:
url.com/api/v1/user?provider=facebook?provider_id=12345
My routes are as follows: routes.rb
namespace :api do
namespace :v1 do
resources :users
match '/:provider/:provider_id', to: 'users#find_by_provider', via: 'get'
end
end
My Strong parameters are:
def user_params
params.require(:user).permit(:name, :age, :location, :provider, :provider_id) if params[:user]
end
My Function is:
def find_by_provider
#user = User.find(params[:provider_id])
respond_to do |format|
format.json { render json: #user }
end
end
Currently, I'm testing with:
url.com/api/v1/facebook/12345
and it is returning:
"{"provider"=>"facebook",
"provider_id"=>"12345"}"
which is good! But I now get the error: "Couldn't find User with id=12345"
Also, somewhat related: occasionally I receive an error that says "param not found: user".
Any suggestions? Thanks!
Change:
#user = User.find(params[:provider_id])
To:
#user = User.find_by(:provider_id => params[:provider_id])
find method will alyways search objects with the id column. Use the where method to search by other criterias/columns
Use:
#user = User.where(provider_id: params[:provider_id]).take
Take a look at http://guides.rubyonrails.org/active_record_querying.html if you want to learn more about the active record query interface.
This is a perfect example where to use find_by! (note the !).
#user = User.find_by!(:provider_id => params[:provider_id])
It works like find_by and returns one User. But if the user is not found it raises an ActiveRecord::RecordNotFound error. That exception is handled by Rails automatically and is turned into a 404 error page.

rails, allow exception in route globbing

i was wondering if i could add an exception to route globbing in rails. in my routes.rb i have
unless params[:not_found].eql? 'admin_data'
match '*not_found', to: 'errors#error_404'
end
im trying to enforce custom error pages, except when a user visits
myapp.heroku.com/admin_data
it doesn't seem like fetching :not_found as a param works. is there a way to add an exception in routes.rb?
if it helps, in my errors_controller i have..
def error_404
#not_found_path = params[:not_found]
end
thank you
update.
i tried doing just
puts :not_found
puts %{not_found}
but doesn't seem to work either hmmm...im trying to see if i can retrieve the params from the user
It would be much more convenient to define allowed routes in routes.rb and add exception handling in application controller for routing error:
class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, :with => :render_not_found
private
def render_not_found
render_error_page_for(404)
end
def render_error_page_for(code)
respond_to do |format|
format.html { render :file => "#{Rails.root}/public/#{code}.html", :status => code, :layout => false }
end
end
i do catch my exception handling in my application controller but unfortunately for admin_data, i don't explicitly set it in routes.rb. it gets configured somewhere in the gem with namespace or something (im not really sure)
but on a positive note... i finally fixed it! i changed my glob and did...
match '*not_found', to: 'errors#error_404', :constraints => {:subdomain => "!(admin_data.)"}
to ignore everything which uses admin_data.

checking valid number of parameters in url rails

I have an url which accepts two parameter.How do i check the number of parameters passed in the routes and discard the request if it contains more than two parameters.
http://localhost:3000/users?product=car&category=honda
I want to check the number of parameters passed.
Thanks in advance
You can do that in you routes.rb with the constraint with a class to do it:
Create the class
class NbParametersConstraint
def initialize(nb)
#nb = nb
end
def matches?(request)
request.params.length <= #nb
end
end
And in your routes use it :
match "/users" => "users#index",
:constraints => NbParametersConstraint.new
After you can do that in your Controller by a filter
class UserController
before_filter :max_params, :only => :index
private
def max_params
render :status => 404 if params.size > 3
end
end

Rails inherited resources usage

I'm using Inherited Resources for my Rails 2.3 web service app.
It's a great library which is part of Rails 3.
I'm trying to figure out the best practice for outputting the result.
class Api::ItemsController < InheritedResources::Base
respond_to :xml, :json
def create
#error = nil
#error = not_authorized if !#user
#error = not_enough_data("item") if params[:item].nil?
#item = Item.new(params[:item])
#item.user_id = #user.id
if !#item.save
#error = validation_error(#item.errors)
end
if !#error.nil?
respond_with(#error)
else
respond_with(#swarm)
end
end
end
It works well when the request is successful. However, when there's any error, I get a "Template is missing" error. #error is basically a hash of message and status, e.g. {:message => "Not authorized", :status => 401}. It seems respond_with only calls to_xml or to_json with the particular model the controller is associated with.
What is an elegant way to handle this?
I want to avoid creating a template file for each action and each format (create.xml.erb and create.json.erb in this case)
Basically I want:
/create.json [POST] => {"name": "my name", "id":1} # when successful
/create.json [POST] => {"message" => "Not authorized", "status" => 401} # when not authorized
Thanks in advance.
Few things before we start:
First off. This is Ruby. You know there's an unless command. You can stop doing if !
Also, you don't have to do the double negative of if !*.nil? – Do if *.present?
You do not need to initiate a variable by making it nil. Unless you are setting it in a before_chain, which you would just be overwriting it in future calls anyway.
What you will want to do is use the render :json method. Check the API but it looks something like this:
render :json => { :success => true, :user => #user.to_json(:only => [:name]) }
authorization should be implemented as callback (before_filter), and rest of code should be removed and used as inherited. Only output should be parametrized.Too many custom code here...

Resources