React, Rails 및 전체 패키지를 결합하여 SPA 웹 어플리케이션 구축
19910 단어 railsreactjavascriptfirstyearincode
나는 내가 어떤 프로젝트를 하고 싶은지, 그리고 내 투자조합이 이해하기 쉬운지 알아보는 데 많은 시간을 들였다.나는 이 프로그램과 운동 프로그램 사이를 왔다 갔다 하며 이 프로그램을 사용하기로 결정했다. 왜냐하면 나는 이미 여러 번 해 놓은 프로젝트를 다시 처리하는 것이 아니라 문제를 해결하기 시작할 수 있기 때문이다.내가 걱정하는 것은 전자음악이 너무 복잡해서 사람들이 빨리 이해하기 어려우므로 이 방향으로 발전하는 것은 일종의 위험이다.그러나 나는 내가 이런 복잡한 문제들을 간소화해서 쉽게 이해하고 사용할 수 있을 것이라고 믿는다.
나는 전자 음악을 좋아한다.House, Techno, Progressive, 그리고'EDM'우산 아래의 모든 소형 하위 유형.나는 매일 인터넷에서 많은 DJ를 주목하고 그들의 믹스를 틀어 놓는다.나는 내가 가장 좋아하는 DJ 플레이어를 찾아내려고 노력해 왔다는 것을 알게 되었다.보통 저는 Shazam과 Soundhound 등 도구를 사용해 보려고 하지만 가정 음악을 식별하는 데 엉망으로 유명하다(특히 DJ가 한 곡을 다른 곡에 섞거나 곡의 관건을 바꾸기 때문이다).인터넷에서 노래 추천과 아티스트 차트를 검색해서 이 노래를 찾을 수 있었으면 좋겠어요.더 복잡한 것은 많은 DJ들이 아직 발표되지 않은 곡을 재생하기 때문에 그들은 인터넷에서 거의 찾을 수 없다.
이 문제를 해결하기 위해 저는 On Rotation - SPA 인터넷 앱을 만들었습니다. 전자 음악의 팬들은 그 중에서 전자 음악을 협동하여 식별하고 그들이 가장 좋아하는 곡을 식별한 후에 알림을 받을 수 있습니다.
특징.
프로젝트 방법
코드를 한 줄 작성하기 전에, 나는 최종 제품을 구상하려고 했다.나는 나 자신에게 물었다.
백엔드
데이터베이스 모드
그리고,drawio에서 제 모델을 그렸고, 데이터 형식, 검증, 요구 사항을 작성했습니다.이것은 정말 내가 사물 간의 관계를 사고하는 데 도움을 준다.그리고 저는 모델 구축과 이동, 모델, 관계 구축과 데이터베이스 제약을 시작한 다음에 모델 검증을 했습니다.나는 seed 파일을 작성하는 동시에 rails 컨트롤러에서 검증/제약과 관계를 정확하게 처리할 수 있도록 노력한다.나는 모든 것이 정상임을 확보하기 위해 이 단계에 한동안 머물렀다.
나는 더 쉽게 이해할 수 있는 코드를 작성하기 위해 모델과db 제약에 대해 열을 사용하여 별명을 인용하기로 결정했다.나는 {foreign_key: }
산열과 {references: }
산열의 이전을 통해 시작했다.
# /db/migrate/create_tracklists.rb
class CreateTracklists < ActiveRecord::Migration[6.1]
def change
create_table :tracklists do |t|
t.string :name, :null => false
t.date :date_played, :null => false
t.references :artist, :null => false, :foreign_key => true
t.string :youtube_url
t.references :creator, :references => :users, :null => false, :foreign_key => { :to_table => :users}
t.timestamps
end
end
Active Record::Base가 belongs_to
방법으로 유사한 산열을 통해 별명 관계 데이터를 전달하는 방법을 알아야 합니다.
# /app/models/tracklsit.rb
class Tracklist < ApplicationRecord
belongs_to :creator, class_name: 'User'
...
end
또 다른 문제는 Tracklist Tracks가 특정한 순서로 Tracklist에서 되돌아와야 하는데, SQL의 구조는 연결표를 만들지 않고 관계 데이터를 질서정연하게 저장하는 것을 허용하지 않는다.이 문제의 해결 방안 중 하나는 Tracklist Tracks를 하나의 체인 테이블로 구성하여 그 전신을 인용하는 열을 만드는 것이다.앞에 있는 트랙리스트 트랙을 가리키는 predessor_id
열을 만들었습니다.
class CreateTracklistTracks < ActiveRecord::Migration[6.1]
def change
create_table :tracklist_tracks do |t|
t.references :tracklist, :null => false, foreign_key: true
t.references :track, :null => false, foreign_key: true
t.time :cue_time
t.integer :predessor_id, :unique => true
t.references :identifier, references: :users, :null => false, foreign_key: { to_table: :users }
t.timestamps
end
end
end
Tracklist 모델에서 기본값id
을 순환하고 덮어쓰는 방법을 사용하고 pull Tracklist tracks out을 질서정연하게 호출합니다.
# /app/models/tracklist.rb
class Tracklist < ApplicationRecord
...
def tracks
tracklist_tracks = self.tracklist_tracks.includes(:track)
current_tracklist_track = tracklist_tracks.find { |tracklist_track| tracklist_track.predessor_id == nil}
array_of_tracks = []
order = 1
loop do
current_track = current_tracklist_track.track
current_track.order = order
order += 1
array_of_tracks << current_track
current_tracklist_track = tracklist_tracks.find { |tracklist_track| tracklist_track.predessor_id == current_tracklist_track.id}
break if current_tracklist_track == nil
end
array_of_tracks
end
end
시리얼화된 데이터
넷플릭스가 belongs_to
에 대한 지원을 중단했기 때문에 데이터를 전방으로 서열화하기 위해서 active_model_serializers
사용하기로 결정했습니다.Gemfile에 추가한 후에 컨트롤러에서 fast_jsonapi
새로운 서열화 프로그램을 신속하게 구축할 수 있습니다.rails g serializer <model_name>
의 좋은 특징은 컨트롤러가 자동으로 active_model_serializers
디렉터리에서 같은 이름의 일치하는 서열화 프로그램을 찾고 rails의 마력 응용을 서열화하는 것이다./serializers
의 또 다른 중요한 특징은 서열화 프로그램에서 active_model_serializers
와belongs_to
관계를 작성하여 모델의 구조와 일치하도록 하는 것이다.
사용자가 두 가지 종류의 알림 (BookmarkedTracklist와 BookmarkedTracklistTrack) 을 받아야 하기 때문에, 나는 알림 서열화 프로그램에서 사용자 정의 데이터 서열화를 구축했다.이렇게 하면 서열화 프로그램은 has_many
클래스 호출의 track
속성만 표시하고 BookmarkedTrack
클래스 호출의 tracklist
속성만 표시합니다.우리는 BookmarkedTracklistTrack
산열을 속성이나 관계에 전달해서 조건 속성을 작성할 수 있으며, 이 방법이truthy 값으로 되돌아오기만 하면 된다.
# /app/serializers/notification_serializer.rb
class NotificationSerializer < ActiveModel::Serializer
attributes :id, :updated_at, :has_unseen_updates
belongs_to :track, serializer: TrackSerializer, if: :is_track?
belongs_to :tracklist, if: :is_tracklist?
def is_track?
object.class == BookmarkedTrack
end
def is_tracklist?
object.class == BookmarkedTracklist
end
end
프런트엔드
구성 요소를 구축하기 시작했을 때, 구성 요소, 용기, 축소기, 조작, 페이지 보기를 분리하는 파일 구조를 찾기가 매우 어려웠다.몇 가지 연구를 한 후에 나는 모든 Reduxjs를 {if: <instance_method>}
디렉터리에 저장하고 모든 페이지 보기를 store
디렉터리에 저장하기로 결정했다.레이아웃 구성 요소를 views
디렉터리에 저장하고 전체 응용 프로그램에서 사용하는 소형 기능 구성 요소에 layout
하위 디렉터리를 제공하기로 결정했습니다.
# .
├── README.md
├── public
└── src
├── App.js
├── components
├── containers
├── index.js
├── layout
│ ├── NavBar
│ └── global
├── store
│ ├── actions
│ └── reducers
└── views
├── Artist
├── Home.js
├── NotFound.js
├── Track
└── Tracklist
React 공유기의 실현
React는 계속해서 하나의 페이지 응용 프로그램에서 모든 구성 요소를 추가하고 삭제하기 때문에 사용자는 React UI를 사용하지 않고 특정 페이지로 수동으로 이동할 수 없습니다.REST-ful URL의 가상을 만들기 위해서 셸 실행 global
을 통해 React Router라는 패키지를 추가했습니다.그리고 나는 npm i react-router-dom
로 <App>
부품을 쌌다.그곳에서 나는 <Router>
과 <Switch>
구성 요소를 사용하여 경로를 구축했다.<Route>
도구를 사용하면 공유기를 통해 제공되는 도구를 사용할 수 있습니다.이렇게 하면 모든 하위 구성 요소가 현재 경로를 쉽게 알고 특정 자원을 식별할 수 있다render
.
// /src/App.js
...
<Switch>
<Route exact path="/" render={() => <Home />} />
<Route exact path="/tracklists" render={(routerProps) => <TracklistIndex {...routerProps} />}/>
...
<Redirect to="/404" />
</Switch>
...
id
구성 요소 끝에 있는 <Redirect>
구성 요소를 사용하면 404페이지로 사용자를 안내하여 그들이 요청한 루트가 존재하지 않는다는 것을 알 수 있습니다.
Redux 및 Thunk 추가
내가 응용 프로그램을 개발함에 따라 상태 관리가 문제가 되기 시작했다.구성 요소는 사용자가 로그인했는지, 사용자 ID가 무엇인지, 특정 구성 요소에 대해 투표했는지, 표지를 만들었는지, 페이지에 표시된 다른 정보를 알아야 합니다.Redux를 입력합니다.
Redux는 구축된react 패키지입니다. 모든 구성 요소의 상태를 하나의 중심 상태로 이동할 수 있고, 모든 하위 구성 요소가 전체 프로그램의 상태를 자유롭게 수정할 수 있습니다.
<Switch>
를 사용하면 다양한 감속기를 중앙 저장소로 이동할 수 있습니다.게다가 combine-reducers
의 강력한 기능으로 우리는 thunk
작업에서 비동기적으로fetch를 호출할 수 있다.
// src/store/reducers/index.js
export default combineReducers({
indexReducer,
tracklistShowReducer,
notificationReducer,
sessionReducer,
});
// src/index.js
import reducer from "./store/reducers/index";
let store = createStore(reducer, composeWithDevTools(applyMiddleware(thunk)));
OnRotation 캡처
/
/ 경로 목록
/ 트랙 목록 / 신규
/tracklist/:id
알림 드롭다운 목록
제안된 항적 식별
날짜 선택기
Reference
이 문제에 관하여(React, Rails 및 전체 패키지를 결합하여 SPA 웹 어플리케이션 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/karsonkalt/putting-together-react-rails-and-a-whole-bunch-of-packages-to-build-a-spa-web-app-d41
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# /db/migrate/create_tracklists.rb
class CreateTracklists < ActiveRecord::Migration[6.1]
def change
create_table :tracklists do |t|
t.string :name, :null => false
t.date :date_played, :null => false
t.references :artist, :null => false, :foreign_key => true
t.string :youtube_url
t.references :creator, :references => :users, :null => false, :foreign_key => { :to_table => :users}
t.timestamps
end
end
# /app/models/tracklsit.rb
class Tracklist < ApplicationRecord
belongs_to :creator, class_name: 'User'
...
end
class CreateTracklistTracks < ActiveRecord::Migration[6.1]
def change
create_table :tracklist_tracks do |t|
t.references :tracklist, :null => false, foreign_key: true
t.references :track, :null => false, foreign_key: true
t.time :cue_time
t.integer :predessor_id, :unique => true
t.references :identifier, references: :users, :null => false, foreign_key: { to_table: :users }
t.timestamps
end
end
end
# /app/models/tracklist.rb
class Tracklist < ApplicationRecord
...
def tracks
tracklist_tracks = self.tracklist_tracks.includes(:track)
current_tracklist_track = tracklist_tracks.find { |tracklist_track| tracklist_track.predessor_id == nil}
array_of_tracks = []
order = 1
loop do
current_track = current_tracklist_track.track
current_track.order = order
order += 1
array_of_tracks << current_track
current_tracklist_track = tracklist_tracks.find { |tracklist_track| tracklist_track.predessor_id == current_tracklist_track.id}
break if current_tracklist_track == nil
end
array_of_tracks
end
end
# /app/serializers/notification_serializer.rb
class NotificationSerializer < ActiveModel::Serializer
attributes :id, :updated_at, :has_unseen_updates
belongs_to :track, serializer: TrackSerializer, if: :is_track?
belongs_to :tracklist, if: :is_tracklist?
def is_track?
object.class == BookmarkedTrack
end
def is_tracklist?
object.class == BookmarkedTracklist
end
end
구성 요소를 구축하기 시작했을 때, 구성 요소, 용기, 축소기, 조작, 페이지 보기를 분리하는 파일 구조를 찾기가 매우 어려웠다.몇 가지 연구를 한 후에 나는 모든 Reduxjs를
{if: <instance_method>}
디렉터리에 저장하고 모든 페이지 보기를 store
디렉터리에 저장하기로 결정했다.레이아웃 구성 요소를 views
디렉터리에 저장하고 전체 응용 프로그램에서 사용하는 소형 기능 구성 요소에 layout
하위 디렉터리를 제공하기로 결정했습니다.# .
├── README.md
├── public
└── src
├── App.js
├── components
├── containers
├── index.js
├── layout
│ ├── NavBar
│ └── global
├── store
│ ├── actions
│ └── reducers
└── views
├── Artist
├── Home.js
├── NotFound.js
├── Track
└── Tracklist
React 공유기의 실현
React는 계속해서 하나의 페이지 응용 프로그램에서 모든 구성 요소를 추가하고 삭제하기 때문에 사용자는 React UI를 사용하지 않고 특정 페이지로 수동으로 이동할 수 없습니다.REST-ful URL의 가상을 만들기 위해서 셸 실행
global
을 통해 React Router라는 패키지를 추가했습니다.그리고 나는 npm i react-router-dom
로 <App>
부품을 쌌다.그곳에서 나는 <Router>
과 <Switch>
구성 요소를 사용하여 경로를 구축했다.<Route>
도구를 사용하면 공유기를 통해 제공되는 도구를 사용할 수 있습니다.이렇게 하면 모든 하위 구성 요소가 현재 경로를 쉽게 알고 특정 자원을 식별할 수 있다render
.// /src/App.js
...
<Switch>
<Route exact path="/" render={() => <Home />} />
<Route exact path="/tracklists" render={(routerProps) => <TracklistIndex {...routerProps} />}/>
...
<Redirect to="/404" />
</Switch>
...
id
구성 요소 끝에 있는 <Redirect>
구성 요소를 사용하면 404페이지로 사용자를 안내하여 그들이 요청한 루트가 존재하지 않는다는 것을 알 수 있습니다.Redux 및 Thunk 추가
내가 응용 프로그램을 개발함에 따라 상태 관리가 문제가 되기 시작했다.구성 요소는 사용자가 로그인했는지, 사용자 ID가 무엇인지, 특정 구성 요소에 대해 투표했는지, 표지를 만들었는지, 페이지에 표시된 다른 정보를 알아야 합니다.Redux를 입력합니다.
Redux는 구축된react 패키지입니다. 모든 구성 요소의 상태를 하나의 중심 상태로 이동할 수 있고, 모든 하위 구성 요소가 전체 프로그램의 상태를 자유롭게 수정할 수 있습니다.
<Switch>
를 사용하면 다양한 감속기를 중앙 저장소로 이동할 수 있습니다.게다가 combine-reducers
의 강력한 기능으로 우리는 thunk
작업에서 비동기적으로fetch를 호출할 수 있다.// src/store/reducers/index.js
export default combineReducers({
indexReducer,
tracklistShowReducer,
notificationReducer,
sessionReducer,
});
// src/index.js
import reducer from "./store/reducers/index";
let store = createStore(reducer, composeWithDevTools(applyMiddleware(thunk)));
OnRotation 캡처
/
/ 경로 목록
/ 트랙 목록 / 신규
/tracklist/:id
알림 드롭다운 목록
제안된 항적 식별
날짜 선택기
Reference
이 문제에 관하여(React, Rails 및 전체 패키지를 결합하여 SPA 웹 어플리케이션 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/karsonkalt/putting-together-react-rails-and-a-whole-bunch-of-packages-to-build-a-spa-web-app-d41
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(React, Rails 및 전체 패키지를 결합하여 SPA 웹 어플리케이션 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/karsonkalt/putting-together-react-rails-and-a-whole-bunch-of-packages-to-build-a-spa-web-app-d41텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)