@torresdyl
2018-03-08T18:06:51.000000Z
字数 10587
阅读 1543
yum install epel-release
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install ./epel-release-latest-7.noarch.rpm
ruby --version
gem list rails
If no rails is installed(no local gem
), you should do:
rvm install 2.4.2
gem update --system
gem install rails bundler
If not working, you must install rvm
:
\curl https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s stable
Here is result:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 24090 100 24090 0 0 75503 0 --:--:-- --:--:-- --:--:-- 75754
Downloading https://github.com/rvm/rvm/archive/1.29.3.tar.gz
Downloading https://github.com/rvm/rvm/releases/download/1.29.3/1.29.3.tar.gz.asc
gpg: Signature made Sun 10 Sep 2017 10:59:21 PM CEST using RSA key ID BF04FF17
gpg: Good signature from "Michal Papis (RVM signing) "
gpg: aka "Michal Papis "
gpg: aka "[jpeg image of size 5015]"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Subkey fingerprint: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GPG verified '/usr/local/rvm/archives/rvm-1.29.3.tgz'
Creating group 'rvm'Installing RVM to /usr/local/rvm/
Installation of RVM in /usr/local/rvm/ is almost complete:
First you need to add all users that will be using rvm to 'rvm' group,
and logout - login again, anyone using rvm will be operating withumask u=rwx,g=rwx,o=rx
.To start using RVM you need to run
source /etc/profile.d/rvm.sh
in all your open shell windows, in rare cases you need to reopen all shell windows.
So, you can add the user to rvm
with:
usermod -a -G rvm <user_name>
Check the group you belong to with:
groups
and log out-log in.
At last, use:
source /etc/profile.d/rvm.sh
and you are done.
Check with rvm
, now available.
Run these again:
rvm install 2.4.2
gem update --system
gem install rails bundler
and we can list rails again, we can see something like:
*** LOCAL GEMS ***
rails (5.1.4)
rails-dom-testing (2.0.3)
rails-html-sanitizer (1.0.3)
sprockets-rails (3.2.1)
cd /var/www/html/
mkdir RoR_demo
cd RoR_demo
rails new demo
(don't run it as root
. )
Then a dir demo
will be created, with all ruby-on-rails files.
Then, cd
into it, and write the ruby version you want to use in .ruby-version
.
echo "2.4.2" > .ruby-version
Gemfile
Edit Gemfile
to add these lines:(add gem pg
, PostgreSQL, and gem unicorn
, the Rack HTTP Service)
group :production do
gem 'pg'
gem 'unicorn'
end
If you like, you can also use the unicorn server during development by declaring the dependency outside of the :production group.
You could optionally wrap the sqlite3 gem in a group for development and test (if you use it to test on your development machine) so that it doesn’t get installed in production:
group :development, :test do
gem 'sqlite3'
end
Then, install all dependencies locally to update Gemfile.lock
:
The parameter --without=production is only needed when bundle install is run the first time, after that Bundler remembers the setting in .bundle/config.
bundle install --without=production
Every time we edit Gemfile
, we must do bundle install
to update.
You can generate a controller for index page and a model
bin/rails generate controller welcome index
bin/rails generate model counter name:string value:integer
If you fail with error Gem Load Error is: Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.
, you have not installed NodeJS yet. Install by:
yum install nodejs
Edit config/routes.rb and set the welcome controller as root route:
Rails.application.routes.draw do
root 'welcome#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Edit app/controllers/welcome_controller.rb and make it use the model object:
class WelcomeController < ApplicationController
def index
counter = Counter.find_or_create_by(name: "default")
counter.value = (counter.value || 0) + 1
counter.save!
render plain: "Counter #{counter.value}; #{Rails.version}/#{RUBY_VERSION}"
end
end
bin/rake db:migrate
bin/rails s
It runs on localhost:3000. Try with explorer with IP.
sudo yum install postgresql postgresql-server postgresql-contrib
rails server
If no controller is defined, error. We must define controller in:
<project_root>/app/controllers/app/application_controller.rb
Like:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def hello
render html: "Hello World!"
end
end
and then change <project_root>/config/routes.rb
:
Rails.application.routes.draw do
resources :users
root 'application#hello'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
And then go back to project root, run rails server
, we can see welcome page.
scaffold
is like a basic frame of the app, including the necessary files. May be too many to digest, but worth trying.
Go back to project root(where you see Gemfile
), and type:
rails generate scaffold User name:string email:string
If it fails, it is because the environment variable XDG_RUNTIME_DIR
is set wrongly. Change it by:
export XDG_RUNTIME_DIR=/run/user/1000
(check your user id by id
, 1000
is mine.)
# for legacy problem, we may use Rake (Make of Rails)
bundle exec rake db:migrate
# Or, after Rails 5, we can use:
rails db:migrate
And then, run the server with:
rails server -b 0.0.0.0 -p 8000 # run server at some IP on some port
In the config/routers.rb
, we write:
root "application#homepage"
In the controller application_controller
, we put:
render file: Rails.public_path.join("templates", "homepage.html"), layout:true # /public/templates/homepage.html
So the file under <project_root>/public/template/
will be read.
HTTP Request | URL | action | Purpose |
---|---|---|---|
GET | /users | list of users | list all users |
GET | /users/1 | show | show user with id 1 |
POST | /users/new | new | add new user |
GET | /users/1/edit | edit | page to edit user 1 |
PATCH | /users/1 | update | update user with id 1 |
DELETE | /users/1 | destroy | delete user with id 1 |
console
Enter:
rails console
Consult:
first_user = User.first
micropost = Micropost.first
posts = first_user.microposts
exit
or `Ctrl
Controller is CamelCase, while files are usually snakeCase.
Undo changes: rails destroy
. Eliminate all generate files and additional changes to files like routes.rb
.
rails generate controller StaticPages home help
rails destroy controller StaticPages home help # can cancel the previous
Or,
rails generate model User name:string email:string
rails destroy model User
We can also undo migrations.
rails db:migrate
rails db:rollback
Or, to go back to the beginning:
rails db:migrate VERSION=0
To check migration version/history, we have:
rails/rake db:migrate:status
or,
rails console
ActiveRecord::Migrator.current_version
ActiveRecord::Migrator.get_all_versions
Full command | Shortcut |
---|---|
rails server | rails s |
rails console | rails c |
rails generate | rails g |
rails test | rails t |
bundle install | bundle |
Ruby on Rails uses TDD. Test code can be generated when generating the controller/model...
test/controllers/static_pages_controller_test.rb
:
test "should get about" do
get static_pages_about_url
assert_response :success
assert_select "title", "About"
end
In app/test/controller/static_page_controller_test.rb
, we can see:
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
end
test "should get help" do
get static_pages_help_url
assert_response :success
end
end
At last, when we run test, if we select something not used in the html, it reports failure too.
Variable in test:
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
def setup
@base_title = "Ruby on Rails Tutorial Sample App"
end
test "should get home" do
get static_pages_home_url
assert_response :success
assert_select "title", "Home | #{@base_title}"
end
test "should get help" do
get static_pages_help_url
assert_response :success
assert_select "title", "Help | #{@base_title}"
end
test "should get about" do
get static_pages_about_url
assert_response :success
assert_select "title", "About | #{@base_title}"
end
end
.erb
)We can execute code in page and insert them with <% %>
and <%= %>
.
<% provide(:title, "Home) %>
...
<%= yield(:title) %>
rails console
Loading development environment
>>
In Ruby we have 3 environments: development, test and production. Now the difference is trivial, but we will see more.
#{a}
: interpolation. Will not interpolate ' '
strings.
2.4.2 :021 > a = 'a'
=> "a"
2.4.2 :022 > b = 'b'
=> "b"
2.4.2 :023 > '#{a} b'
=> "\#{a} b"
2.4.2 :024 > "#{a} b"
=> "a b"
The use of ' '
: auto-escape.
2.4.2 :030 > print "\n"
=> nil # interprete it
2.4.2 :031 > print '\n'
\n => nil # escape and print the literal
2.4.2 :038 > puts "#{city}\t#{state}"
Madrid Madrid
=> nil
2.4.2 :039 > puts '#{city}\t#{state}'
#{city}\t#{state}
=> nil
puts
prints and new line; print
no new line.
object
in Ruby:
>> "foobar".empty?
=> false
>> {}.empty?
=> true
>> [].empty?
=> true
flow control:
>> if s.nil?
>> "It is nil"
>> elsif s.empty?
>> "It is empty"
>> elsif s.include?("foo")
>> "Included"
>> end
&& (“and”), || (“or”), and ! (“not”)
>> puts "Both strings are empty" if x.empty? && y.empty?
We can use unless
above in place of if
.
Ternary: <condition> ? <action1> : <action2>
nil.to_s
=> ""object.nil?
=> true
nil
is the only object in boolean is false.
>> !!nil
=> false
>> !!0
=> true # 0 is true
>> s = 'racecar'
>> s.reverse
=> "rececar"
>> s == s.reverse
=> true
Ruby has an implicit return: if no return
, return the last statement evaluated. Or, with return
, which can be like this:
def method()
return "A" if str.empty?
return "B"
end
To include a module in Ruby, we use include
. Helper modules are included by default, needs no extra work.
split: split string with space, one or more.
>> "foo bar foobar".split
=> ["foo", "bar", "foobar"]
get array element: a[0]
, a.first
, a.last
, a.second/third/fourth/fifth
(a[1~4])
You can call empty?
, include?(obj)
, sort(!)
, reverse(!)
, shuffle(!)
. !
means change the array itself, without !
is copying.
Add element: push(obj)
, <<
, or append
. Can be chained.
Ruby arrays can contain different type of things.
>> a = ["foo"]
=> ["foo"]
>> a << 7
=> ["foo", 7]
We can join array to convert it to string.
>> a = ["foo", 7]
=> ["foo", 7]
>> a.join
=> "foo7" # join to string
>> a.join(', ')
=> "foo, 7"
range: first inclusive. ..
: last inclusive, ...
: last not inclusive.
>> (0..9).to_a
=> [0, 1, 2, ..., 9]
>> (0...9).to_a
=> [0, 1, 2, ..., 8]
>> a = %w[foo bar foobar] # generate string array
=> ["foo", "bar", "foobar"]
>> a[0..1]
=> ["foo", "bar"]
>> a[1, -1] # select to the last, without using length.
=> (original array)
form a natural letter array
>> a = ('a'..'z').to_a
=> ["a", "b", "c", ..."z"]
>> a[-26]
=> "a"
>> a[-27]
=> nil # cannot find element more than length
Short block: {|var| ...}
.
Long block:
<method> do |var|
...
...
end
Note that the |var|
part is in the block, not out of it.
For example:
>> (1..5).each { |i| puts 2*i }
2
4
6
8
10
=> 1..5
>> (1..5).each do |i|
?> puts 2*i
>> end
2
4
6
8
10
=> 1..5 # returns the range
|var|
represents the variable iterated.
map
creates a new array to return. each
returns the original array. Compare:
>> (1..5).map {|i| i**2}
=> [1, 4, 9, 16, 25] #returns an array
Or we can write:
>> ('a'..'Z').map(&:downcase)
=> ["a", "b", "c", "d", ..."z"]
The best example is this:
def yeller(array)
a = array.each(&:upcase)
puts a
puts array
puts "a: " + a.join
puts "array: " + array.join
puts "array == a:" + array==a?
end
yeller(%w[a, b, c])
def yeller(array)
a = array.map(&:upcase)
puts a
puts array
puts "a: " + a.join
puts "array: " + array.join
end
yeller(%w[a, b, c])
Result:
a,
b,
c
a,
b,
c
a: a,b,c
array: a,b,c
A,
B,
C
a,
b,
c
a: A,B,C
array: a,b,c