Rails3 ActiveResource Post Call delivers an empty Parameter Hash - ruby-on-rails-3

I am trying to create a new "Person" in a Sinatra API app from a Rails3 app using ActiveResource and Json. In Rails3, I created a "Person" model and using ActiveResource I correctly call the API, which correctly reads the URL, but no parameters seem to get passed with the object.
From Rails3 Person Model:
class Person < ActiveResource::Base
self.site = "http://127.0.0.1:9393/"
self.collection_name = "person/add"
self.format = :json
end
From the Rails3 console:
u=Person.new({"last_name"=>"Bill", "first_name"=>"Smith"})
=> #<Person:0xb73176f0 #attributes={"last_name"=>"Bill", "first_name"=>"Smith"}, #prefix_options={}>
puts u.attributes
=> last_nameBillfirst_nameSmith
u.save
=> True
From the Sinatra app:
puts #app.params.keys
=> Nil
puts #app.params['last_name']
=> Nil
puts #app.params[:last_name]
=> Nil
Using the IRB Console this works:
Net::HTTP.post_form(URI.parse('http://127.0.0.1:9393/user/add.json'),{'first_name' => 'Smith', 'last_name' => 'Bill'})
Can someone please give some direction as to what I missed or am doing wrong thank you.

Person object should know attributes, as you did on console. When doing Person.find, it gets attrs via activeresource, but Person.new doesn't know them so that any-way to tell to Person is required at Person.new like the following:
class PeopleController < ApplicationController
...
def new
#person = Person.new(:name=>nil, :age=>nil, ...)
end
...
Does this answer?

Related

How to test after_create method in rspec?

I have after_create method as follow:
company.rb
class Company < ActiveRecord::Base
after_create :create_subscriptions
def create_subscriptions
subscription=Subscription.create(:company_id => self.id, :subscription_dt => Date.today, :is_active => 'Y', :last_renewal_dt => Date.today + 2,:user_id => self.users.first.id)
subscription.save
end
end
While i create a company after_create method called and enter data in subscription table.
In rspec I created company and it success fully created. But how do test "create_subscriptions" method? whoch call in after create. Can i do query in rspec code? like
rspec code:
#company = create(:company)
#sub = Subscription.find(:first,:conditions => ['company_id= ?', #company.id] )
expect(#sub.company_id).should eq(#company.id)
is it ok?? I did not see this type of query in rspec code in my google searching. Have use stub or mock in this?
can anyone please guide me? I think i have to use stub and mock but i don't know how to use them?
Thanks,
Your idea is correct but your code looks "obsolete" (for Rails 2.x)
I can suggest the following variant
#company = create(:company)
#company.reload
expect(#company.subscriptions).not_to be_empty
# additionally you can test attributes
subscription = #company.subscriptions.first
expect(subscription.is_active).to eq('Y')
PS it is necessary to add has_many :subscriptions to Company and belongs_to to Subscription

Rails Mailer error: wrong number of arguments (1 for 0)

Hello im reading Agile Web Development With Rails 4th Edition Book but im getting an error at 'Task H: Sending Mail'
I have mailer order_notifier.rb
class OrderNotifier < ActionMailer::Base
default :from => "name#email.tld"
def received
#order = order
mail(:to => order.email, :subject => 'Pragmatic Store Order Confirmation')
end
def shipped
#order = order
mail(:to => order.email, :subject => 'Pragmatic Store Order Shipped')
end
end
i have templates /views/order_notifier/ received.text.erb and shipped.text.erb like
Dear <%= #order.name %>
Thank you for your recent order from The Pragmatic Store.
You ordered the following items:
<%= render #order.line_items %>
We'll send you a separate e-mail when your order ships.
i run it from OrdersController
im not sure if use current_cart or #cart but i guess it doesnt matter
def create
#order = Order.new(params[:order])
#order.add_line_items_from_cart(current_cart)
##order.add_line_items_from_cart(#cart)
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
OrderNotifier.received(#order).deliver
the error im getting tels me that received method has one argument more than it needs (#order) but thats how its written in the book.. error:
ArgumentError in OrdersController#create
wrong number of arguments (1 for 0)
Where is the mistake ? Thank you.
The mistake is that your received method in the OrderNotifier does not take an argument, but your controller is passing it one. You should modify the notifier to take one argument, order.
On a side note, I do not recommend reading Agile Web Development With Rails.

Rails 3: How can I make a route helper that generates different routes depending on an object property or method?

I'm making an app in Ruby on Rails 3.1.3. I have different types of users (i.e. admin, operator, advertiser, etc...), and each has a different main (or home) page. I want to make a route helper that will give me the respective route for the home page of the current logged in user by using something like home_path. This is mainly for redirecting after certain actions (I want to redirect back to the respective home pages depending on the type of user).
I already have some methods available such as current_user (returns the current logged in user), current_user.admin? (returns true if the current logged in user is admin), current_user.operator?, etc.
Right now I'm using a helper method to do this, but it doesn't seem like a very Rails way to do it. The code follows anyway:
def home_path(params = {})
user = current_user
case user
when user.admin?
params = {:controller => 'administrators', :action => 'index'}.merge(params)
when user.advertiser?
params = {:controller => 'advertisers', :action => 'show', :id => user.advertiser_id}.merge(params)
when user.operator?
params = {:controller => 'callcenter', :action => 'index'}.merge(params)
else
params = {:controller => 'posts', :action => 'home'}.merge(params)
end
url_for(params)
end
I figure this should be done with constrained routes, but I still don't get how it could be done to depend on the .admin?, .operator?, etc. methods. Any help on this would be greatly appreciated.
Using a helper method is fine for this. It should probably end up in your controller, rather than a view helper, though, which gives it access to the current_user. With some cleanup, you can arrive at something that ain't half bad with the same idea you have now.
module DefaultHomeHelper
DEFAULT_PARAMS = { controller: :posts, action: :home }.freeze
ROLE_SPECIFIC_PARAMS = {
admin: { controller: :administrators, action: :index },
advertiser: { controller: :advertisers, action: :show },
operator: { controller: :callcenter, :action: :index }
}.freeze
def home_path(params = {})
url_for params.reverse_merge(ROLE_SPECIFIC_PARAMS[current_user.role] || DEFAULT_PARAMS)
end
end
I've made the assumption you can be more direct and ask your User object to just tell you its role instead of guessing one after the other. You will almost certainly need to tweak the code to accomodate whatever you're calling this on your user. I've also used the newer hash syntax, but if you're running or accommodating Ruby < 1.9 you will need to update. I've used symbols for the actions and controller names, too, because I like referring to objects and methods with symbols instead of strings (and controllers and actions are objects and methods).
You could do a simple include DefaultHomeHelper in your ApplicationController to use this. You can also make it available to your views with helper_method :home_path.

Error when using ActionMailer in Rails3

Currently i'm trying to port my application to Rails 3.0 from 2.3.14 and I'm struck on the following error and this works fine in 2.3.14
My mailer code looks like
def welcome_mail(host,vendor_name,from, batch, sent_at = Time.now)
template = MailTemplate.get_template(self.class.to_s,:welcome_mail.to_s,vendor_name,
:greeting => batch.greeting, :batch => batch, :host =>host)
#html_message = template.html_message
#text_message = template.text_message
mail( :subject => batch.subject, :to => get_recipients(batch), :from => from, :date => sent_at ) do |format|
format.html
format.text
end
end
I pick up the email content from DB using MailTemplate model.
And my mailer view (welcome_mail.text.html.erb and welcome_mail.text.plain.erb contain only this line
<%=#html_message%> - welcome_mail.text.html.erb
<%=#text_message%> - welcome_mail.text.plain.erb
Inside the template, that is fetched from DB, i'm using a named route (which is a nested route) profile_batch_url and is supposed to produce a url like /profile/:profile_id/batch/:batch_id
But when I try to create a message
mail = UserMailer.welcome_email(request.host_with_port,get_vendor_name(),email, batch)
I'm getting the following error
NameError: undefined local variable or method `controller' for #<MailTemplate:0x000000060dff38>
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/activemodel-3.0.17/lib/active_model/attribute_methods.rb:392:in `method_missing'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.0.17/lib/active_record/attribute_methods.rb:46:in `method_missing'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/actionpack-3.0.17/lib/action_view/helpers/url_helper.rb:31:in `url_options'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/actionpack-3.0.17/lib/action_dispatch/routing/url_for.rb:131:in `url_for'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/actionpack-3.0.17/lib/action_view/helpers/url_helper.rb:99:in `url_for'
/usr/local/rvm/gems/ruby-1.9.3-p327/gems/actionpack-3.0.17/lib/action_dispatch/routing/route_set.rb:201:in `profile_batch_url'
(erb):5:in `text_message'
Can anyone help me in fixing this?
Thanks,
Sivakumar

rails3 routing and yaml based API, using devise and cancan

I have an application that will have an API, with a /api/v1/ namespace:
namespace :api do
namespace :v1 do
resources :gateways do
resources :mappings do
# maybe more stuff
end
end
end
end
my application uses devise and cancan.
My mappings controller down in app/controllers/api/v1/mappings_controller.rb works correctly from rspec test cases if I leave out :format=>:yaml (asking for HTML, and getting a 406).
If I ask for :yaml, devise seems to think that my test user is not allowed.
My test case is stupid simple:
describe "Agent access to mappings" do
it "gets a list of mappings that includes test_user mapping" do
#test_agent = users(:firewallagent)
sign_in(#test_agent)
get :show, {:gateway_id => 1, :id => 2} #, :format => :yaml
assert_response 200
end
end
I can't see anything in devise/warden which would be format specific, but maybe I've missed it.
The fault was that :format=>:yaml needs to go into the first hash, rather than into the second hash for get. So:
get :show, {:gateway_id => 1, :id => 2, :format => :yaml}