Use `raise_error` matcher in Rspec
Yesterday I came accross a tricky useage of raise_error
matcher in rspec, first I try to use the one line syntax is_expected.to
rb
it { is_expected.to raise_error(SomeError) }
but I got an eror which stops the test before the test is finished.
It is confusing in the first time, because is_expected.to
is shortcut for expect(subject)
.
Then I found this excellent explanation in Github isses.
So expect(subject)
is not a block, subject is executed instantly, so rspec will stop before evaluating raise_error
matcher.
In order to make it work, we can make subject itself a block
```rb
subject { -> { raise SomeError } }
it { is_expected.to raise_error(SomeError) }
```
But this syntax is creepy, instead it’s better to use
```rb
subject { raise SomeError }
expect { subject }.to raise_error(SomeError)
```
Serialize Non-ActiveRecord Model Using ActiveModel::Serializer in Rails
Recently I’ve been working in backend which connects to another API, you may need to send a specific format of JSON data which is not the same as database resource.
Create A Serializable Resource
Currently I’m using active_model_serializers 0.10.0. From the documentation we know ActiveModel::Serializer
wraps a serializable resource, to create a serializable resource we need to create a plain old Ruby object inherits ActiveModelSerializers::Model
, then create a corresponding serializer.
For example:
```rb
class MyModel < ActiveModelSerializers::Model
def initialize(title:, body:)
@title = title
@body = body
end
def converted_body
# do something
end
end
```
class MyModelSerializer < ActiveModelSerializers::Serializer
attributes :converted_body
end
Handling Nested JSON
You can use has_many
, has_one
method in ActiveModel::Serializer
to handle nested json, although it doesn’t mean the same with Rails model relations.
For example:
```rb
class MyModel < ActiveModelSerializers::Model
def initialize(object: object)
@title = title
@body = body
end
def
def related_models
related_models.map do |related_model|
RelatedModel.new(related_model: related_model)
end
end
end
```
class MyModelSerializer < ActiveModelSerializers::Serializer
has_many :related_models
end
ActiveModelSerializers::Serializer
will automatically look for a serializer named RelatedModelSerializer
.
Reference
Find more explainations in https://github.com/rails-api/active_model_serializers/tree/0-10-stable#what-does-a-serializable-resource-look-like
Plot Financial Data Using Matplotlib (super basic)
import libraries
In order to plot the data, we need to import libraries for dataframe and plot, also set plot inline if you’re using a notebook.
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
plot stock price
Code is super simple, you just need to set the index of the dataframe to timestamp. If you find the figure to small, use pylab to set the figure size.
python
from pylab import rcParams
rcParams['figure.figsize'] = 50,13
apple_data = market_train_df[market_train_df['assetCode'] == 'AAPL.O']
apple_data.set_index('time')['close'].plot(grid = True)
compare multiple plots
Then I’m trying to sanitize the data by looking at the figure it self, I want to plot all suspicious assets.
python
for code in suspicious_asset_code:
apple_data = market_train_df[market_train_df['assetCode'] == code]
apple_data.set_index('time')['close'].plot(grid = True)
This only gives me one figure with all assets, it’s ugly. I want to plot them one by one.
Subplot will give you figures put up together, use
python
# treat the whole figure as a grid, specify how many rows and columns you wanna plot and the index of the current sub plot
fig.add_subplot(row, columns, index)
Then you’ll get graphs all together to detect abnormal data.
Configure Mailgun settings in Rails app
Recently I’m learning to create a Rails 5 api only application with an android mobile application. I want to send a activation email after user registered from the android app, and I found there is a free Mailgun add-on on Heroku. It’s perfect choice to start to play with because you can send up to 100 messages/hour without being charged. The documentation is good enough but I do found several steps confusing.
Firstly, you need to create a Mailgun account and add your credit card information, otherwise you can’t send to recipents other than authorized ones(which means test only).
Then, use the test domain(XXX@XXX.mailgun.org) to ensure Mailgun not being blocked by your test mail address(In my case I use qq mail at first, it actually blocks all traffic from mailgun). After that, you need to add a custom domain. Go to your domain name provider and configure DNS settings as following the steps of Mailgun instructions. In my case I use Namecheap and it took me a while(a cup of coffee) for Mailgun to verify my domain.
After your custom domain is active, configure your development environment and make sure it works. In my case I use smtp instead of api call, the settings are for example:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.mailgun.org",
:port => 587,
:domain => mydomain.club',
:user_name => "postmaster@mydomain.club",
:password => XXXX
}
Then start your rails server and see if the mail was delivered. I spent quite a few hours here because at first my emails weren’t delivered. I refered to the log and showed Mailgun accepted the mail address, and one minute later a ESP throttling message showed up. The reason is Mailgun being blocked by certain ISP(like qq mail, in this case I have to use an extra mail hosting service), so I couldn’t see any mail sent inbox.
If OK in development environemnt, change your production settings as well, it should work as well.
Troubleshooting with Installing Broadcom Wireless Drivers in Ubuntu Desktop
Days before, I changed the operating system of my old laptop from Windows7 to Ubuntu Desktop, I installed Ubuntu from a USB stick from my friend. After installing I found I Broadcom wireless driver wasn’t installed so I couldn’t connect to my WiFi. I tried several ways then found the solution, hope it my be helpful.
To download the driver from Internet, you need to connect with Ethernet.
Open Software and Update from system and configuration, open the fifth tab optional drivers and see if wireless driver comes out or not.
Make sure allowing downloading drivers from Internet is checked in the first tab Ubuntu Software.
If it still doesn’t come out, you need to manually install it from terminal, use lspci -nn -d 14e4:
command to see which network card you’re using, then install the corresponding driver. http://askubuntu.com/questions/55868/installing-broadcom-wireless-drivers offers an excellent guide.
life ( 4 )
music ( 1 )
programming ( 12 )
spirituality ( 1 )
language-learning ( 1 )
About Me

I'm a university student in the last year, also a web developer. I love exporing cultures, learning languages and making BGM music!