rails functional testing issue - ruby-on-rails

When I do
get :inside, :format => :xml, :lat2 => "41", :lng2 => "-73.9", :lat1 => "40", :lng1 => "-74", :category => "girl", :order => "date"
with my routes.rb includes:
get 'images/inside/:lat1/:lng1/:lat2/:lng2/:order/:category', :to => "images#inside"
I get
ActionController::RoutingError: No route matches {:lng1=>"-74", :category=>"girl", :lat2=>"41", :format=>:xml, :lng2=>"-73.9", :order=>"date", :lat1=>"40", :action=>"inside", :controller=>"images"}
But when I do
get :inside, :format => :xml, :lat2 => "41", :lng2 => "-73", :lat1 => "40", :lng1 => "-74", :category => "girl", :order => "date"
it works!
The only difference is the decimal value of lng2.
Note that if routes.rb has no params, it works, but I need those

As far as I can tell, it's because your value has a period. By default, Rails (at least Rails3) routes cannot contain periods. To work around this, see http://avdi.org/devblog/2010/06/18/rails-3-resource-routes-with-dots-or-how-to-make-a-ruby-developer-go-a-little-bit-insane/

I bet the decimal point is making Rails think that there's a format being specified (e.g. .xml or .js).
You might be able to get around it using a regex, something like what's described here: http://zargony.com/2009/05/05/routing-parameters-with-a-dot

Related

Russian symbols in url and route constraints

There are such urls in my app:
local/alphabetical/service/Ю
local/alphabetical/service/Б
local/alphabetical/service/Ж
I would like to allow only symbols Ю, Б, Ж in the url
But routes.rb:
get "/alphabetical/:type/:letter" => "alpha#index",
:constraints => { :type => /good|service/, :letter => /[ЮБЖ]/ },
:as => "alpha"
for http://local/alphabetical/service/Ю Gives me an error:
Routing Error
No route matches [GET] "/alphabetical/service/%D0%AE"
How to setup a constraint in routes.rb file to allow only Ю, Б, Ж symbols?
Thanks.
Thanks #phoet for reply, its very useful.
Will someone interesting...
For my case the solution is:
Product model:
class Product < ActiveRecord::Base
LETTERS = %w( А Б В Г Ґ Д Е Є Ж З І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ю Я )
end
routes.rb:
get "/alphabetical/:type/:letter" => "alpha#index",
:constraints => lambda { |req| req.params[:type] =~ /good|service/ and req.params[:letter] =~ /[#{Product::LETTERS.join}]/i },
:as => "alpha"
I think that you need to handle the unescaping of those characters yourself. Have a look at this example here: Redirect when using I18n with Rails is encoding the forward slash as %2F
had a similar issue, post for the sake of an example.
resources :listings, path: "объявления" do
get ":kind(/:category(/:subcategory(/:state(/:city))))",
constraints: lambda { |req| %w(работа недвижимость услуги продажи).include? req.params[:kind] },
to: "listings#search",
as: "search",
on: :collection
end

Alternatives to using splat token with delegate in Rails 3.2.13 (Ruby 1.8.7)

Quick question: I want to delegate a bunch of methods to an association in my model:
z13u_methods = [
:isbn_cleaned,
:oclc_cleaned,
:contents_cleaned,
:summary_cleaned,
:title_statement,
:is_serial?
]
delegate *z13u_methods, :to => :z13u, :prefix => true, :allow_nil => true
This works just fine when I'm running Rails 3.2.13 on Ruby 1.9.3. However, when I run Rails 3.2.13 (the same version) on Ruby 1.8.7, I encounter the following error:
syntax error, unexpected tSYMBEG, expecting tAMPER
delegate *z13u_methods, :to => :z13u, :prefix => true, ...
where the :to is highlighted.
I guess in Ruby 1.8 the splatted array has to be the final parameters (except for a block name). Is there some other way to to splat an array for this situation?
If you're only using z13u_methods for that delegate call then you could do this:
delegate_args = [
:isbn_cleaned,
:oclc_cleaned,
:contents_cleaned,
:summary_cleaned,
:title_statement,
:is_serial?,
{ :to => :z13u, :prefix => true, :allow_nil => true }
]
delegate *delegate_args
I think that's the basic pattern that you need. There are other ways to get there of course:
delegate *(z13u_methods + [{ :to => :z13u, :prefix => true, :allow_nil => true }])
# If you don't mind changing z13u_methods
delegate *z13u_methods.push(:to => :z13u, :prefix => true, :allow_nil => true)
# If you don't want to change z13u_methods
delegate *z13u_methods.dup.push(:to => :z13u, :prefix => true, :allow_nil => true)
# ---------------------^^^
There are probably more variations on that theme, those are just a couple options that come to mind.
As far as using 1.8.7 is concerned, upgrade ASAP, I don't think 1.8.7 is even supported anymore.

Rails 3.1.3 custom routing by date

How to make path helpers for this route?
resources :news
match 'news/:year/:month/:day' => 'news#show',
:constraints => { :year => /\d{4}/, :month => /\d{2}/, :day => /\d{2}/ },
:as => 'newsdate'
I tried it many ways, but it not works:
link_to news.created_at.strftime '%d.%m.%Y ', newsdate_path(:year => '2011', :month => '11', :day => '11')
I get app error for this line by GET http://localhost:3000/news:
ArgumentError in News#index
Showing /home/foxweb/work/dev/app/views/news/index.html.slim where line #6 raised:
wrong number of arguments (2 for 1)
How to make it right way?
P.S. http://localhost:3000/news/2011/11/11 works fine.
Oh, that's common mistake. You need to take strftime arguments in braces.
link_to news.created_at.strftime('%d.%m.%Y'), newsdate_path(:year => '2011', :month => '11', :day => '11')
That's all!

Ruby add_item for eBay

I am attempting to write a ruby on rails app that posts an item to eBay. Cody Fauser/Garry Tan have a gem called ebayApi which is built on top of the ebay gem. When I attempt to post an item, I am getting an error back from ebay that says the condition ID is required for this category. I have found a category that does not require the condition, and I can post to that category. Searching through the eBay API documentation, I have found a tag conditionID under the "item" class. However, in the documentation for ebayAPI, there is no such tag. Looking back at the ebay API documentation, there is an older way to specify condition, using lookup_attributes. I have noted that the return xml is coming in API version 745, and Garry Gan's updated of the ruby interface is running version 609. I have tried using the lookup, and seem to get the same error (condition required). I am using the following code to specify the item:
#ebay = Ebay::Api.new :auth_token => #seller.ebay_token
item = Ebay::Types::Item.new( :primary_category => Ebay::Types::Category.new(:category_id => #ebayTemplate.categoryID),
:title => #ebayTemplate.name,
:description => #ebayTemplate.description,
:location => #ebayTemplate.location,
:start_price => Money.new((#ebayTemplate.startPrice*100).to_d, #ebayTemplate.currency),
:quantity => 1,
:listing_duration => #ebayTemplate.listingDuration,
:country => #ebayTemplate.country,
:currency => #ebayTemplate.currency,
:payment_methods => ['VisaMC', 'PayPal'],
:paypal_email_address => '********#gmail.com',
:dispatch_time_max => 3,
:lookup_attributes => [Ebay::Types::LookupAttribute.new( :name => "Condition", :value => "New")],
# :attribute_sets => [
# Ebay::Types::AttributeSet.new(
# :attribute_set_id => 2919,
# :attributes => [
# Ebay::Types::Attribute.new(
# :attribute_id => 10244,
# :values => [ Ebay::Types::Val.new(:value_id => 10425) ]
# )
# ]
# )
# ],
:shipping_details => Ebay::Types::ShippingDetails.new(
:shipping_service_options => [
# ShippingServiceOptions.new(
# :shipping_service_priority => 2, # Display priority in the listing
# :shipping_service => 'UPSNextDay',
# :shipping_service_cost => Money.new(1000, 'USD'),
# :shipping_surcharge => Money.new(299, 'USD')
# ),
Ebay::Types::ShippingServiceOptions.new(
:shipping_service_priority => 1, # Display priority in the listing
:shipping_service => #ebayTemplate.shipSvc,
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_surcharge => Money.new((#ebayTemplate.shipSurcharge*100).to_d, #ebayTemplate.currency)
)
],
:international_shipping_service_options => [
Ebay::Types::InternationalShippingServiceOptions.new(
:shipping_service => 'USPSPriorityMailInternational',
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_service_priority => 2,
:ship_to_location => #ebayTemplate.shipToLocation
)
]
),
:return_policy => Ebay::Types::ReturnPolicy.new (
:description => 'this product for suckers only!',
:returns_accepted_option => 'ReturnsAccepted'
)
#:condition_id => 1000
)
#response = #ebay.add_item(:item => item)
As you can see, it is just a mutation of the example given by Cody Fauser. The condition_id at the bottom will bring up an error as there is no such attribute. It seems to me there is no facility for this in the gem since the requirement came into existence after the gem was created. I have not been able to find any other gems to connect with ebay. I have also noticed, there are very little complaints about this even though people are still downloading the gem (10 people downloaded it today). I think there are quite a number of people writing for ebay. Is there a key word I am missing to specify the condition? A work around that people have been using? Another gem I have missed?
There is an existing item_conditions_codes.rb in the gem's type directory and only has two values New and Used. Guess you could add more values in there. However still needs mapping to ID's per the updating (and changed from Attributes) method
You have to modify in the gem library in .. ruby/1.8/gems/ebayapi-0.12.0/lib/ebay/types/item.rb
and add the following new lines
# added to allow ConditionID to be pushed into XML
numeric_node :condition_id, 'ConditionID', :optional => true
then in your ruby ebay code use the following convention
:condition_id => 1500,
At least that seems to work for me right now.

How do you make Rails route everything under a path to a Rack app?

I'm trying to capture all requests to /dav and all paths nested under that to a Rack handler:
match "/dav" => RackDAV::Handler.new(:root => 'davdocs')
match "/dav/*whatever" => RackDAV::Handler.new(:root => 'davdocs')
Do I really have to make two routes for this, or is there a way to express this as one route (one line)?
I think it should be enough to use
match "/dav(/*whatever)" => RackDAV::Handler.new(:root => 'davdocs')
Optional parameters are very briefly described in the Rails Routing guide under "Bound parameters"
match '/dav(/*dav_section)', :to => Proc.new { |env| [200, {"Content-Type" => 'text/plain'},["Here we are in Dav"]]}

Resources