Recent notes
RSS feed![Default_avatar_30](https://www.gravatar.com/avatar/6cbc53789fd6f4e35c8f12caca647a39?size=30&default=http://apidock.com/images/default_avatar_30.png)
Step-By-Step Guide to Building Your First Ruby Gem
Nowadays all the functionalities in Rails are built as Ruby gems. For example we can use devise gem for the authentication part of the application. It’s like a package or library that is written in Ruby programming language. Moreover it can be imported and used by others in their programs.
Step 1 Bundler is like a dependency management tool for Ruby, which is also used by Rails. We will use Bundler for the basic gem structure. It helps us to install the correct versions of the gem and forces us to use the same in the application. So the command for that is, gem bundler install After bundling, we should specify the gem “name” that we are going to create i.e. Bundle gem “testgem” will create a repository shown below
So in this we can see the basic gem structure. Under the lib folder, version file will be used to mention the version of the Gem. We can edit the version as per our convenience and release it that will be the version in Rubygems.
Step 2 We will consider testgem.gemspec, with testgem as the name of the gem that we will create for sample. It will be used to set up the gem on rubgems, for e.g., name of the gem, summary, description, files that are required in this project, test files that are used to testing the files in the project etc.
Rake file: – This makes releasing the new versions of the gem, and also helps other developers to check the test cases if they are going to modify the particular gem. After the rake, we should create a test folder and test cases for each segments will be included here in the app directory.
Step 3 Planning to make a rubygem, then we need to analyse the requirements what to build up and what all functionalities should be included in that. While generating, we should create a sample.rb file inside lib folder and create own class with namespace because the other plugin has also the same classes then it will get conflict in the names. And require the sample.rb file in the testgem.rb file like reqiure “testgem/sample”.
Step 4 We have require “bundler/gem_tasks” in rake file so when we run rake release, it will release the gem to ruby gems and make it available. Push to git repository
![Default_avatar_30](https://www.gravatar.com/avatar/6cbc53789fd6f4e35c8f12caca647a39?size=30&default=http://apidock.com/images/default_avatar_30.png)
SOCKET LIBRARY IN RUBY ON RAILS
There are basically two levels of accessing network services in case of rails .
The socket and network libraries are such important parts of integrating Ruby applications with the Internet and other communications-based environments.
One is through socket libraries provide low level access to connection oriented and connection-less protocols. Where user can implement client and server connection. Ruby is also having Network libraries that provide users a high level access to specific network protocols like FTP,HTTP and Etc.
At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols. Ruby also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on.
What are Sockets?
Sockets are basically a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents. Sockets can be implemented on different channels : Unix domain sockets, TCP, UDP, and so on. The socket library mainly provides specific classes and interface for handling a transports.
A SimpleClient:
Hereis a very basic client program which will open up a connection to a given port and given host. Ruby class TCPSocket provides open function to open a socket. The TCPSocket.open(hosname, port ) opens a TCP connection to hostname & theport.
Once socket is open, you can actually read that particular thing like IO object. When it’s done, just remember to close it, as you close that file. The following code connects to a given host and port, reads any available data from the socket, and then exits:
require ‘socket’ # Socket in standard library
hostname = ‘localhost’
port = 8080
s = TCPSocket.open(hostname, port)
while line = s.gets # Gets and Read the lines from the socket
puts line.chop # And print with platform line terminator end
s.close # socket Closed
A Simple Server: To write Internet servers, we basically use this TCPServer class. A TCPServer object is a factory for TCPSocket objects. Now call TCPServer.open(hostname, port function to specify a port for your service and create a TCPServer object. Next, call the accept method of the returned TCPServer object. This particular method waits till client connects to the port you specified above, and then returns a TCPSocket object that basically represents the connection to that client.
require ‘socket’ # Get sockets from stdlib server = TCPServer.open(8080) # Socket to listen on port 8080 loop { # Servers run forever
client = server.accept # Wait for a client to connect client.puts(Time.now.ctime) # Send the time to the client client.puts "Closing the connection. Bye!" client.close # Disconnect from the client
}
Now run this server in background and then run above client to see the result.
![Default_avatar_30](https://www.gravatar.com/avatar/a1ffa5e1a9980ad0cd80ed05a7c3f0a0?size=30&default=http://apidock.com/images/default_avatar_30.png)
foreign_key option
It is also possible to specify that add_foreign_key should be added to the schema:
add_reference(:products, :supplier, foreign_key: true)
![Default_avatar_30](https://www.gravatar.com/avatar/830e2d5b84e996c8f9007bc1cd4193c0?size=30&default=http://apidock.com/images/default_avatar_30.png)
Active Record Import
With activerecord-import, you’d just add your records to an array and call import:
records_to_import = pricing_data.map do |location, price| Inventory.new(location: location, price: price) end Inventory.import records_to_import
![Default_avatar_30](https://www.gravatar.com/avatar/5b2b185c814bb25f2f95a1152e58f033?size=30&default=http://apidock.com/images/default_avatar_30.png)
Location of this method in older versions
Before v3.2.1, this method was in ActiveRecord::Base.create .
![Default_avatar_30](https://www.gravatar.com/avatar/5b2b185c814bb25f2f95a1152e58f033?size=30&default=http://apidock.com/images/default_avatar_30.png)
Where this method moved to
After v3.1.0, this method moved to ActiveRecord::Persistence::ClassMethods#create .
![Default_avatar_30](https://www.gravatar.com/avatar/4e6aa196471a575d9b92752773e51797?size=30&default=http://apidock.com/images/default_avatar_30.png)
Careful with arel column
I use what @equivalent suggests a lot but be careful, you MUST state the direction otherwise methods like take/last/first will fail silently!
StatusChange.arel_table[‘created_at’]. asc
not:
StatusChange.arel_table[‘created_at’]
![Default_avatar_30](https://www.gravatar.com/avatar/8c0db83f64d78acaf545989464ad6713?size=30&default=http://apidock.com/images/default_avatar_30.png)
![Default_avatar_30](https://www.gravatar.com/avatar/070aab749e66879e8ad53d186cc064b5?size=30&default=http://apidock.com/images/default_avatar_30.png)
Why module_function creates a private method, when including the module?
What’s the intention for doing that?
![Default_avatar_30](https://www.gravatar.com/avatar/6e6e22d81a1f4f394f62301be40c2e20?size=30&default=http://apidock.com/images/default_avatar_30.png)
`value` or `text` method with parameter.
If your value or text method requires a parameter, like to_s(:select) then you need to create a separate method that references that in your model, like:
def to_s_select to_s(:select) end
You can’t pass it in as a string like 'to_s(:select)'.
You have to use :to_s_select or 'to_s_select'.
![Default_avatar_30](https://www.gravatar.com/avatar/a2c3d6ac3dae424b007081f667210ab2?size=30&default=http://apidock.com/images/default_avatar_30.png)
RE: RE: FALSE: Creates record by given attributes only if table is empty
keredson is still a little off on the behavior.
>> Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
This isn’t right, as if you look at the source it calls: “first || create(attributes, &block)”
So in the example of:
User.first_or_create(email: 'derek@somwhere.com')
it would find the first user with any email, and return it. And thats it. The attributes passed in as params are only used in the event that first returns no matches, and create is called.
I’m using it in a way similar to:
Foo.where(bar: baz_params[:bar]).first_or_create(baz_params)
This will find the first Foo where bar is equal to the bar sent from baz_params. If none is found, it will create it. It’s useful for me when importing large amounts of data where I know there will be duplicate records.
![Default_avatar_30](https://www.gravatar.com/avatar/4848b214e10b429e514ec91af4e1ea17?size=30&default=http://apidock.com/images/default_avatar_30.png)
Should include information about optional block
If a block exists, will return true if any records in the relation is true for the given block. Otherwise, returns true is there are any records.
![Default_avatar_30](https://www.gravatar.com/avatar/4848b214e10b429e514ec91af4e1ea17?size=30&default=http://apidock.com/images/default_avatar_30.png)
Description
Selects the first record within a relation if it exists, otherwise creates a new record with the optional attributes.
![Default_avatar_30](https://www.gravatar.com/avatar/dd2d775dea75b381edb1bbf0600a0907?size=30&default=http://apidock.com/images/default_avatar_30.png)
No grammatical error
rajivekjain:
“A, B, and C” is correct in English, and is preferred by most style manuals. “A, B and C” is also correct in English. See en.wikipedia.org/wiki/Serial_comma
![Default_avatar_30](https://www.gravatar.com/avatar/9f603b48405f66cc4f4341a2f2425caa?size=30&default=http://apidock.com/images/default_avatar_30.png)
Default values
By default :on_update and :on_delete have :restrict value.
![Default_avatar_30](https://www.gravatar.com/avatar/794349372513ad17e1e61aa7fbff7f1c?size=30&default=http://apidock.com/images/default_avatar_30.png)
![Default_avatar_30](https://www.gravatar.com/avatar/97339bb1262db04c5a5b63637dd2549b?size=30&default=http://apidock.com/images/default_avatar_30.png)
RE: FALSE: Creates record by given attributes only if table is empty
Dino’s comment was almost certainly due to a misunderstanding of the API, a mistake I made myself the first time I used it, and one I’ve witnessed multiple others make as well.
The fact that this method takes an attributes parameter leads one to think the passed params are the criteria for the selection. At first glance it would appear it would be used like this:
User.first_or_create(email: 'derek@somwhere.com')
Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
In reality it should be used like this:
User.where(email: 'derek@somwhere.com').first_or_create
And the attributes param. isn’t used in 99% of use cases. (If at all - the provision for the block that executes only on create fully duplicates what the attributes parameter can do in a much more obvious way.)
IMHO this is simply a bad API that one just needs to be aware of. But it’s unfair to knock dino for what’s likely a highly common misreading.
![Default_avatar_30](https://www.gravatar.com/avatar/ad8d4636dd0b8fcceff22d01adedc787?size=30&default=http://apidock.com/images/default_avatar_30.png)
FALSE: Creates record by given attributes only if table is empty
I very much doubt that dino’s comment was ever correct, but it certainly isn’t correct now. The behavior liantics describes is correct.
![Default_avatar_30](https://www.gravatar.com/avatar/670f30d60f74035203752fc751d1cc50?size=30&default=http://apidock.com/images/default_avatar_30.png)
link broken
http://apidock.com/rails/ActionDispatch/Request/body <- request body link
![Default_avatar_30](https://www.gravatar.com/avatar/1087d3c42f816af723f0c25216a535a5?size=30&default=http://apidock.com/images/default_avatar_30.png)
Text values for enum
There is way to have text values for enum. It is useful to have localized select options and latin values in database. 1) User model: enum kind: { ‘текст’=>‘text’, ‘изображение’=>‘picture’, ‘звук’=>‘audio’, ‘видео’=>‘video’ } 2) Edit view: <%= select_tag ‘user[kind]’, options_for_select(User.kinds, @user.kind) %>
![Default_avatar_30](https://www.gravatar.com/avatar/ae823fe7f85ddc410add2511eaaae546?size=30&default=http://apidock.com/images/default_avatar_30.png)
group on hash
‘
def group_by_hash hash, value hash.group_by do |k,v| v > value ? "Big" : "Small" end end marks = {"Chair" => 30, "Table" => 40, "Bed" => 60, "stool" => 20} group_by_hash(marks, 30)
![Default_avatar_30](https://www.gravatar.com/avatar/aae8a096939117430c37280e7897f32c?size=30&default=http://apidock.com/images/default_avatar_30.png)
Generate Token
For generate a token, make this:
def generate_token self.token = SecureRandom.uuid end
SecureRandom return a number random and the uuid make this number be unique. This a good idea for use in shopping cart, for example
![Default_avatar_30](https://www.gravatar.com/avatar/82ce1ff7e97bbfc992a91fc8cb01c279?size=30&default=http://apidock.com/images/default_avatar_30.png)
Fetch with default value
You can specify default value as a fail-back if a hash doesn’t have a given key.
{a: false}.fetch(:b, true) => true {a: false}.fetch(:a, true) => false
It is useful especially in the case where you want to set default value for a method.
def initialize(args) @foo = args.fetch(:foo, 1) @bar = args.fetch(:bar, 2) # This can take over the following way. # `@bar = args[:bar] || 2` # => @bar is overwritten if caller specifies nil for :bar! end
![Default_avatar_30](https://www.gravatar.com/avatar/b91a97f8a79bd0c29eb4e51431773aef?size=30&default=http://apidock.com/images/default_avatar_30.png)
Params of conditions
You can pass an proc for o callback with the conditions
before_action :initial_value, only: [:index, :show], unless: -> { @foo.nil? } before_action :initial_value, only: [:index, :show], if: -> { @foo }
![Default_avatar_30](https://www.gravatar.com/avatar/b91a97f8a79bd0c29eb4e51431773aef?size=30&default=http://apidock.com/images/default_avatar_30.png)
Params of conditions
You can pass an proc for o callback with the conditions
after_action :initial_value, only: [:index, :show], unless: -> { @foo.nil? } after_action :initial_value, only: [:index, :show], if: -> { @foo }
![Default_avatar_30](https://www.gravatar.com/avatar/ff7afae5b23125e25e18ad8c0404bd78?size=30&default=http://apidock.com/images/default_avatar_30.png)
the method to make 'day' disappear.
If you wanna show “year” and “month” only, you can use “order” to do it:
select_date(Date.current, order: [:year, :month])
That’s it.
![Default_avatar_30](https://www.gravatar.com/avatar/2e5e7d94324be62b6b328ecb067a1913?size=30&default=http://apidock.com/images/default_avatar_30.png)
Creates record by given attributes only if table is empty
This method first searches the table for ANY FIRST RECORD, not the one matching given attributes. If no record is found at all, it creates one using the specified attributes. This might be misunderstood in many cases.
![Default_avatar_30](https://www.gravatar.com/avatar/5226311ea9ba44d7e34180a3aa18457c?size=30&default=http://apidock.com/images/default_avatar_30.png)
Errno::EEXIST
When Errno::EEXIST is raised, it indicates there are permission issues, rather than an existing item.
![Default_avatar_30](https://www.gravatar.com/avatar/4478529eeeb6cb0970e3fcece19004cc?size=30&default=http://apidock.com/images/default_avatar_30.png)
What about Marshal remote code execution risks?
Good suggestion about using Marshal to avoid cycles, astgtciv, but what about the security risks of doing that?
See http://ruby-doc.org/core-2.2.2/Marshal.html where it states:
By design, ::load can deserialize almost any class loaded into the Ruby process. In many cases this can lead to remote code execution if the Marshal data is loaded from an untrusted source. As a result, ::load is not suitable as a general purpose serialization format and you should never unmarshal user supplied input or other untrusted data. If you need to deserialize untrusted data, use JSON or another serialization format that is only able to load simple, ‘primitive’ types such as String, Array, Hash, etc. Never allow user input to specify arbitrary types to deserialize into.
![Default_avatar_30](https://www.gravatar.com/avatar/81c3e738c6c4d4ec282b2df918cf882c?size=30&default=http://apidock.com/images/default_avatar_30.png)
Also implemented by other classes
It’s worth noting that this method is also implemented by other classes like Proc, Range and even String.
Most of these are missing proper examples, but you can find some useful examples here: