我正在研究 pinterest 克隆,但在尝试创建新图钉时遇到了一些问题。我在 3 毫秒内完成了 422 个不可处理的实体(视图:0.1 毫秒 | ActiveRecord:0.3 毫秒) 我不知道还有什么可以尝试的。起初我以为这是我的真实性令牌,我尝试了protect_from_forgery,除非:-> { request.format.json?但仍然不起作用。 有什么建议???
routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root to: 'static_pages#root'
namespace :api, defaults: { format: :json } do
resources :users, only: [:show,:new, :create, :index]
resource :session, only: [:new, :create, :destroy, :show]
resources :pins, only: [:create, :show, :index, :edit, :destroy]
resources :boards, only: [:create, :show, :edit, :destroy]
end
end
用户.rb
class User < ApplicationRecord
attr_reader :password
validates :username, presence: true, uniqueness: true
validates :password_digest, :session_token, presence: true
validates :password, length: { minimum: 6 }, allow_nil: true
after_initialize :ensure_session_token
has_many :pins,
foreign_key: :author_id,
class_name: :Pin
has_many :boards,
foreign_key: :author_id,
class_name: :Board
has_many :pins_in_boards,
through: :boards,
source: :boards_pins
def self.find_by_credentials(username, password)
user = User.find_by(username: username)
return nil unless user
user.is_password?(password) ? user : nil
end
def password=(password)
@password = password
self.password_digest = BCrypt::Password.create(password)
end
def is_password?(password)
BCrypt::Password.new(self.password_digest).is_password?(password)
end
def ensure_session_token
self.session_token ||= SecureRandom.urlsafe_base64
end
def reset_session_token!
self.session_token = SecureRandom.urlsafe_base64
self.save
self.session_token
end
end
users_controller.rb
class Api::UsersController < ApplicationController
def show
@user = User.find_by(username: params[:id])
if @user
render :show
else
render json: @user.errors.full_messages, status: 404
end
end
def new
@user = User.new
render :new
end
def index
@users =User.all
render :index
end
def create
@user = User.new(user_params)
if @user.save
sign_in(@user)
render "api/users/show"
else
render json: @user.errors.full_messages, status: 422
end
end
private
def user_params
params.require(:user).permit(:password, :username)
end
end
pins_controller.rb
class Api::PinsController < ApplicationController
def index
@pins = user.pins
end
def new
@pin = Pin.new(user_id: current_user.id)
render :new
end
def show
@pin = Pin.find(params[:id])
render :show
end
def create
@pin = current_user.pins.new(pin_params)
if @pin.save
render :show
else
render json: @pin.errors.full_messages, status: 422
end
end
def edit
@pin = Pin.find(params[:id])
unless @pin.author_id == current_user.id
render "api/pins/show"
else
render :edit
end
end
def destroy
pin = current_user.pins.find(params[:id])
pin.destroy
end
private
def pin_params
params.require(:pin).permit(
:title,
:description,
:url,
:author_id,
:photo
)
end
def user
@user ||= User.find(params[:user_id])
end
def pin
@pin ||= current_user.pins.find(params[:id])
end
end
pin.rb
class Pin < ApplicationRecord
validates :title, :description, :author_id, presence: true
belongs_to :user
belongs_to :board
has_many :boards
has_one_attached :photo
has_many :users,
through: :boards,
source: :author
end
creat_pin_form_container.jsx
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import PinForm from './pin_form';
import { createPin } from '../../actions/pins_actions';
import { openModalForm, closeModalForm } from '../../actions/modal_form_actions';
const mapStateToProps = state => ({
pin: {
title: '',
description: '',
photoFile: null
},
formType: 'New Pin'
});
const mapDispatchToProps = dispatch => ({
action: pin => dispatch(createPin(pin)),
closeModalForm: () => dispatch(closeModalForm())
});
export default connect(mapStateToProps, mapDispatchToProps)(PinForm);
pin_form.jsx
import React from 'react';
class PinForm extends React.Component {
constructor(props) {
super(props);
this.state = this.props.pin;
this.handleSubmit = this.handleSubmit.bind(this);
this.handleFile = this.handleFile.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const formData = new FormData();
formData.append('pin[title]', this.state.title);
formData.append('pin[description]', this.state.description);
formData.append('pin[url]', this.state.url);
formData.append('pin[photo]', this.state.photoFile);
this.props.action(formData, this.state.id);
}
update(field) {
return e => this.setState({ [field]: e.currentTarget.value });
}
handleFile(e){
this.setState({ photoFile: e.currentTarget.files[0] })
}
render() {
return (
<div className="pin-form-container">
<form onSubmit={this.handleSubmit}>
<div className="create-edit-form-top">
<nav className="pin-form-header">
<div onClick={this.props.closeModalForm} className="close-pin"><img src={window.cancelURL} /></div>
</nav>
</div>
<div className="new-pin"> <h3>{this.props.formType}</h3></div>
<div className="create-edit-form-left">
<label className="photo-upload">
<img src={this.state.photoUrl} />
<input
type="file"
onChange={this.handleFile}
/>
</label>
</div>
<div className="create-edit-form-right">
<label className="create-edit-form-title">
<input
type='text'
value={this.state.title}
placeholder="Add your title"
onChange={this.update('title')}
/>
</label>
<label className="create-edit-form-description">
<textarea
cols="30"
rows="1"
value={this.state.description}
placeholder="Tell everyone what your Pin is about"
onChange={this.update('description')}
/>
</label>
<label className="add-url">
<input
type='text'
placeholder="Add a destination link"
onChange={this.update('url')}
/>
</label>
</div>
<button className="pin-submit" type='submit'>Save</button>
</form>
</div>
);
}
}
export default PinForm;
答案 0 :(得分:0)
使用
protect_from_forgery with: :null_session