I am trying to learn and write an update API and to start small I am passing a single params in the API and and try to get the response.
the controller :
module Api
module V1
class OrderApiController < ApiController
def order_update
response = Hash.new
result = Hash.new
#order = Order.find(params[:id])
if #order.update_attributes(order_params)
result['order_id'] = order.id
response['result'] = result
response.merge! ApiStatusList::OK
else
response.merge! ApiStatusList::INVALID_REQUEST
end
render :json => response
end
private
def order_params
params.require(:order).permit( :id)
end
end
end
end
the api route in routes.rb is:
match 'mobile/order_update' =>'order_api#order_update'
The url link what I give is
http://localhost:3000/api/v1/mobile/order_update?key=docket&id=1
However this throws the following error
ActionController::ParameterMissing at /api/v1/mobile/order_update
param is missing or the value is empty: order
I dont know what am I doing wrong. I am new to Rails as well as API generation. Please help
This is caused by the order_params method, in which you're requiring order(expecting order to be a nested hash), whereas, you're not nesting it.
An approach you could take is to visit:
http://localhost:3000/api/v1/mobile/order_update?key=docket&order[id]=1
Also, I see you're setting #order instance variable, but in your control block(if #order.update_attributes), you're using a local variable which would give you another error.
I'd recommend you go through the Hartl Tutorial as there are a lot of things you'd be able to learn from there
UPDATE
Based on the new error mentioned in the comment, I think you should rather be visiting:
http://localhost:3000/api/v1/mobile/order_update?order[key]=docket&id=1
This is assuming your orders table has a column key based on the params being set
Also, change your order_params to:
private
def order_params
params.require(:order).permit( :key) #since you cannot update a primary key, but I guess you want to update the key column
end
The solution I used is as follows
In my order_api_controller.rb , I have Changed
def order_update
response = Hash.new
result = Hash.new
#order = Order.find(params[:id])
if #order.update_attributes(order_params)
result['order_id'] = order.id
response['result'] = result
response.merge! ApiStatusList::OK
else
response.merge! ApiStatusList::INVALID_REQUEST
end
render :json => response
end
and edited it to this
def order_update
response = Hash.new
result = Hash.new
debugger
#order = Order.find(params[:order][:id]) # passed the order symbol into params
if #order.update_attributes(order_params)
result['order_id'] = #order.id # Modified local variable to instance variable as per oreoluwa's suggestion
response['result'] = result
response.merge! ApiStatusList::OK
else
response.merge! ApiStatusList::INVALID_REQUEST
end
render :json => response
end
And used the url as Follows
http://localhost:3000/api/v1/mobile/order_update?key=docket&order[id]=1
This seems to do the trick
Related
Rails 5.2
In my inventories_controller.rb, I have the following:
before_action :fetch_product, only: [:show]
def show
........
end
def fetch_product
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
This works fine, when I do: http://0.0.0.0:3000/sku/12345678
I am trying to implement search functionality, so I modified nventories_controller.rb as follows:
def fetch_product
if params.has_key?(:search) && !params[:search].blank?
product = Product.find_by_sku(params[:search])
if !product
params = params.except[:search]
redirect_to product_show_path, alert: 'Product was not found'
end
params = params.merge!(:sku, product.sku)
end
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
When I do: http://0.0.0.0:3000/sku/12345678
I get an instant error message:
undefined method `has_key?' for nil:NilClass
Using my debugger, I find that on entry into the fetch_product method, params is nil
Any idea what's going on?
params = params.merge!(:sku, product.sku) modifies the hash in place and returns nil, don't do that assignment, just call params.merge! (if you still want to do the assignment, remove the "!").
Personally, I wouldn't modify the params hash unless it's really really needed, I would use another variable.
Trying to integrate Shoppe(https://github.com/tryshoppe/shoppe) and Stripe payment (https://github.com/tryshoppe/shoppe-stripe) onto my Rails application by following this Docs/Tutorial (https://tryshoppe.com/docs/payment-gateways/stripe). Not sure why im getting this error...
Couldn't find Shoppe::Order with 'id'=
def payment
#order = Shoppe::Order.find(session[:current_order_id])
if request.post?
if #order.accept_stripe_token(params[:stripe_token])
redirect_to checkout_confirmation_path
end
The error is telling you that it can't find a Shopped::Order with an id of nothing.
This means the argument session[:current_order_id] contains no information.
You need to look into correcting whatever is causing the value that correlates with the :current_order_id key in the session hash to be blank.
There's a bug in the shoppe documentation. In order to access current_order you need to create the helper in your ApplicationController like so. I then suggest referencing as current_order.id instead.
ApplicationController:
private
def current_order
#current_order ||= begin
if has_order?
#current_order
else
order = Shoppe::Order.create(:ip_address => request.ip)
session[:order_id] = order.id
order
end
end
end
def has_order?
session[:order_id] && #current_order = Shoppe::Order.includes(:order_items => :ordered_item).find_by_id(session[:order_id])
end
helper_method :current_order, :has_order?
OrdersController:
def payment
#order = Shoppe::Order.find(current_order.id)
### rest of your code here ###
end
I have a piece of code in Rails,
def create
#registration = Registration.new(registration_params)
if #registration.save
redirect_to #registration.paypal_url(registration_path(#registration))
else
render :new
end
end
I took it from tutorial. But I need just in this line:
#registration.paypal_url(registration_path(#registration))
Now, about my own controller, feed_controller, where
def create
#feed = Feed.new(check_params)
end
In the view erb file I put:
#feed.paypal_url(feed_path(#feed))
In my feed.rb (model):
def paypal_url(return_path)
values = {
business: "merchant#gotealeaf.com",
cmd: "_xclick",
upload: 1,
return: "#{Rails.application.secrets.app_host}#{return_path}",
invoice: id,
amount: course.price,
item_name: course.name,
item_number: course.id,
quantity: '1'
}
"#{Rails.application.secrets.paypal_host}/cgi-bin/webscr?" + values.to_query
end
Rake routes:
feed GET /:locale/feed(.:format) feed#index
feed#create POST /:locale/feed/create(.:format)
feed#new feed_new GET /:locale/feed/new(.:format)
feed#destroy feed_destroy GET /:locale/feed/destroy(.:format)
feed#edit feed_edit GET /:locale/feed/edit(.:format)
feed#update feed_update GET /:locale/feed/update(.:format)
But it prints the next error:
undefined method `paypal_url' for <#Feed::ActiveRecord_Relation:0x007fee24f5fc98>
How can I fix it? What is the problem?
UPDATE
def index
#current_user_is = current_user.email
session[:email] = #current_user_is
session[:id] = current_user.id
unless (current_user.member.present?)
#member = Member.new(:user_id => current_user.id)
#member.save()
redirect_to '/feed'
else
#new_feed = Feed.new
#feed = Feed.where(:member_id => current_user.member.id)
#category = Category.all
render 'home/uploads'
end
end
Simply use def self.paypal_url(return_path) instead of def paypal_url(return_path).
Explanation
You ran into your problem by defining a Class Method instead of an Instance Method, there's other posts discussing this.
The basic difference is, when defining:
def self.get_some_url
# code to return url of an instance
end
you can easily get the desired url of any objects, as in a view:
<% #feeds.each do |feed| %>
<%= feeds.get_some_url %>
<% end %>
Now calling Feed.get_some_url on the class would make no sense. Which url of the thousands would it call?
But there is a lot of use for class methods (where you define the method without self as you did)
def get_top_5
# code to return the top 5 most viewed feeds
end
Since this has nothing to do with a single instance, you define it for the entire Class. Leading to this call: Feed.get_top_5, which makes perfectly sense.
The second problem was not understanding the difference between where & find, this post will help you out with that.
I have a rest api that that is getting a string sent to it. The problem is that I need to use this string (which will always be a number) for an id, which needs to be an integer. I am trying to accomplish this by turning the string into an integer when it is received. This is what I have been trying to do, but I get the error message listed bellow when I try:
def create
respond_with #classroom = Classroom.create(classroom_params)
if #classroom.save
#do stuff
else
#do other stuff
end
end
def classroom_params
params.require(:classroom).permit(:period.to_i, :teacher.to_i, :subject.to_i)
end
Here is the error:
NoMethodError (undefined method `to_i' for :period:Symbol):
app/controllers/api/v1/classroom_controller.rb:42:in `classroom_params'
app/controllers/api/v1/classroom_controller.rb:24:in `create'
Try this. permit method requires a list of symbols to allow. You can only do classroom_params.map(&:to_i) since you want all the parameters as integer. If there is anything in classroom_params that you want as string, you will have to convert the ones that you want as integers explicitly.
def create
attributes = classroom_params
#classroom = Classroom.create(:teacher_id => attributes[:teacher].to_i,
:student_id => attributes[:student].to_i,
:subject_id => attributes[:subject].to_i)
respond_with
if #classroom.save
#do stuff
else
#do other stuff
end
end
def classroom_params
params.require(:classroom).permit(:period, :teacher, :subject)
end
I have a Rails 3 blog. I want every Post to have a "Like" button. Clicking on it will save this action to the database and store to cookies on the user who has just liked the Post (for disallowing same action again).
I wrote a simple action to do this:
def like
render :nothing => true
id = params[:post_id]
cookies.permanent[:like_history] ||= []
unless cookies.permanent[:like_history].include? id
cookies.permanent[:like_history] << id
#post = Post.find(id)
#post.update_column(:likes, #post.likes + 1)
end
end
But I'm getting NoMethodError (undefined method '[]' for nil:NilClass) when I try to log things. It points to this line: cookies.permanent[:like_history] ||= [] as if cookies.permanent isn't an array.
Am I doing something wrong with cookies here?
Turns out, the ||= operator counts as "reading" by rails standards, which actually makes sense. You can't "read" with cookies.permanent[:symbol], that's for writing, you read with cookies[:symbol]. So I modified that line to read:
cookies.permanent[:like_history] = "" unless defined? cookies[:like_history]
I think you have something stored in cookies.permanent[:like_history] which is not an Array. So make it nil or covert to array using to_a and try your code.
def like
render :nothing => true
cookies.permanent[:like_history] = nil #or cookies.permanent[:like_history] = cookies.permanent[:like_history].to_a
id = params[:post_id]
cookies.permanent[:like_history] ||= []
unless cookies.permanent[:like_history].include? id
cookies.permanent[:like_history] << id
#post = Post.find(id)
#post.update_column(:likes, #post.likes + 1)
end
end
Once it works remove that line you added.