How to get id from post route in Sinatra - ruby

I have a factory that is creating a student. All of the required fields are being filled in and created in the factory. When I post a new student, I am never getting that student, just the one created in the factory? How Can I get the id of the new student from the POST?
students.rb
FactoryGirl.define do
factory :student do
sequence(:id)
sequence(:first_name){|n| "Tom"}
sequence(:last_name) {|n| "Dick"}
sequence(:password) {|n| "test"}
sequence(:email){ |n| "person#{n}#example.com" }
school
end
end
student_spec.rb
require File.dirname(__FILE__) + '/spec_helper'
describe 'admin' do
before :all do
#student=FactoryGirl.create(:student)
end
it 'should save student information' do
params={
post:{
first_name: 'Abraham',
last_name: 'Lincoln',
address: '1400 Pennsylvania Ave.',
city: 'Washington',
state: 'D.C.',
zip: '11111',
email: 'alincoln#whitehouse.gov',
password: 'I cant tell a lie',
major: 'Law',
level: 'Graduate',
employment: 'President',
participation: 'Yes',
participation_research: 'No',
what_doing_now: 'Watching a Play',
ethnicity: 'White',
eth_other: 'none',
education_level: 'Doctorate',
hometown: 'Springfield, IL',
twitter_handle: '#TheRealAbe',
facebook_url: 'therealabe',
prior_education: 'None',
prior_AS: 'None',
prior_BS: 'None',
prior_MS: 'None',
prior_Other: 'None',
awards_honors: 'Ended Civil War',
scholarships: 'Full',
other_inbre_funding: 'yes',
deleted: 'false'
}
}
post '/admin/students/add/', params, {'rack.session'=>{student_id:#student.id, admin_authorized:true}}
updated_student = Student.get(#student.id)
expect(updated_student.first_name).to eql('Abraham')
#expect(updated_student.last_name).to eql('Dick')
#expect(updated_student.address).to eql('1400 Pennsylvania Ave.')
end
end

I can't know for certain without seeing the route, but it seems to me that you are calling POST twice, once in the route, and once within the params hash. However, without seeing your routes, I can't be sure if that's an issue.
Another thought comes from reading your spec. Are you attempting to create a new student(POST) or are you attempting to edit the student? If you are attempting to edit an existing student, this should probably be referring to a separate route, PUT or a PATCH by RESTful conventions. As was mentioned above, a POST route does not need an id, precisely because it is creating a new student, which is where it will create the id, and the id is set by the database, not manually.
a reference to the above: http://guides.rubyonrails.org/v2.3.11/routing.html
I hope this at least points in the right direction. :D

Related

FactoryBot creates records even when a record is provided

I use factorybot to create records in development sometimes. However, it's creating a bunch of extra data that I wasn't expecting.
I have two factories:
FactoryBot.define do
factory :user do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
email { "#{first_name}.#{last_name}#example.com" }
end
factory :post do
user { create(:user) }
title { Faker::Lorem.sentence }
end
end
If I run FactoryBot.create(:post) in the rails console, it will create a new post with a new user. What I didn't expect is that if I do FactoryBot.create(:post, user: User.first), it would create a post associated with the first user, but still create a new record. So, I get this:
irb(main):001:0> User.count
=> 1
irb(main:002:0> FactoryBot.create(:post, user: User.first)
=> #<Post id: 1, title: 'Lorem Ipsum', host_id: 1>
irb(main:003:0> User.count
=> 2
Everything works, it just creates a new user record that isn't attached to anything. Is there anyway to stop that from happening?
You don't need to tell FactoryBot to create(:user). Just remove it.
factory :post do
user
title { Faker::Lorem.sentence }
end
https://devhints.io/factory_bot

Reading a JSON object in Ruby on Rails

I'm a Ruby on Rails beginner and I'm trying to convert a static website I've made into Rails app where I can store customers and quote data. I'm trying to do this as a RESTful API where my site sends a JSON object containing the customer's information. I check to see if the email in the JSON object matches any of the emails I have in my database and if it does I send back the id of that customer. If not then I create a new customer and send back that id. The problem I'm having is that no matter how I write it, my rails app is not reading the JSON data, so if I have nothing in my database it creates a customer with all null attributes and when I run it again it goes "Oh, I have customer with a null email" and returns that customer.
{
"fname": "William",
"lname": "Shakespeare",
"email": "wshakespeare#test.com",
"bname": "MyCompany",
"primary": "555-555-5555",
"secondary": ""
}
Here's an example of my JSON object.
Here's how my controller is looking:
class CustomersController < ApplicationController
skip_before_action :verify_authenticity_token
wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form]
def create
#query = Customer.where(:email === params[:email])
if #query.empty? == true
redirect_to action: "new", status: 301
else
#theid = #query.first.id
render json: {status: 'SUCCESS', message: 'Existing customer', theid:#theid}
end
end
def new
Customer.create(fname: params[:fname], lname: params[:lname], email: params[:email], bname: params[:bname], primary: params[:primary], secondary: params[:secondary])
render json: {status: 'SUCCESS', message: 'New customer', theid: Customer.last.id}
end
Any help would be greatly appreciated. Thanks.

fetch larger images from Facebook with Koala using the get_connection method

The documentation of the Koala gem gives an example how to fetch posts from Facebook, including a picture.
client = Koala::Facebook::API.new(oauth_token)
client.get_connection('someuser', 'posts',
{limit: #options[:max_items],
fields: ['message', 'id', 'from', 'type',
'picture', 'link', 'created_time', 'updated_time'
]})
Below this example the documentation makes a note:
You can pass a ‘type’ hash key with a value of ‘small’, ‘normal’, ‘large’, or ‘square’ to obtain different picture sizes, with the default being ‘square’. Also, you may need the user_photos permission.
Unfortunately, this doesn't seem to work:
client.get_connection("officialstackoverflow", "posts",
{limit: 5, type: "large", fields: [:picture, :message, :type]})
Unfortunately, I get the same picture as I would get when omitting the type param. How do I have to pass the type hash correctly?

Batch insert multiple records with Mongoid?

I am reading through this Stackoverflow answer about how to insert multiple documents in Mongoid in one query. From the answer I read:
batch = [{:name => "mongodb"}, {:name => "mongoid"}]
Article.collection.insert(batch)
I need an example to understand how this works. Say we have the Article class:
class Article
include Mongoid::Document
include Mongoid::Timestamps
field :subject, type: String
field :body, type: String
field :remote_id, type: String
validates_uniqueness_of :remote_id
belongs_to :news_paper, :inverse_of => :articles
end
And the I e.g. create an array of articles:
[ {subject: "Mongoid rocks", body: "It really does", remote_id: "1234", news_paper_id: "abc"},
{subject: "Ruby rocks", body: "It really does", remote_id: "1234", news_paper_id: "abc"},
{subject: "Rails rocks", body: "It really does", remote_id: "5678", news_paper_id: "abc"} ]
How do I create them, and at the same time make sure the validation catches that I have 2 remote_id's that are the same?
If you add a unique indexing for remote_id field, MongoDB will take care the uniqueness of this field
index({ remote_id: 1 }, { unique: true })
Don't forget to run create_indexes: rake db:mongoid:create_indexes
After that, you are free to use Article.collection.insert(batch).

How to stop DataMapper from double query when limiting columns/fields?

I'm not sure if I'm at fault here or if my approach is wrong with this.
I want to fetch a user (limiting columns/fields only to name, email, id):
#user = User.first(:api_key => request.env["HTTP_API_KEY"], :fields => [:id, :name, :email])
The output in the command line is correct as follows:
SELECT "id", "name", "email" FROM "users" WHERE "api_key" = '90e20c4838ba3e1772ace705c2f51d4146656cc5' ORDER BY "id" LIMIT 1
Directly after the above query, I have this code:
render_json({
:success => true,
:code => 200,
:user => #user
})
render_json() looks like this, nothing special:
def render_json(p)
status p[:code] if p.has_key?(:code)
p.to_json
end
The problem at this point is that the #user variable contains the full user object (all other fields included) and DataMapper has made an additional query to the database to fetch the fields not included in the :fields constraint, from the logs:
SELECT "id", "password", "api_key", "premium", "timezone", "verified", "notify_me", "company", "updated_at" FROM "users" WHERE "id" = 1 ORDER BY "id"
My question is this: how do I stop DM from performing the additional query? I know it has to do with it's lazy loading architecture and that returning the #user variable in JSON assumes that I want the whole user object. I particularly don't want the password field to be visible in any output representation of the user object.
The same behaviour can be seen when using DM's own serialisation module.
I think you should use an intermediate object for json rendering.
First, query the user from database :
db_user = User.first(:api_key => request.env["HTTP_API_KEY"], :fields => [:id, :name, :email])
Then, create a "json object" to manipulate this user :
#user = { id: db_user.id, name: db_user.name, email: db_user.email }

Resources