Last active
August 29, 2015 14:03
-
-
Save 1syo/319f237637cf522c8c9f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container"> | |
<% if flash[:notice] %> | |
<div class="alert alert-success"> | |
<%= flash[:notice] %> | |
</div> | |
<% end %> | |
<h1>Users</h1> | |
<%= form_for(@user_import, url: import_admin_users_path, | |
html: {method: :post, multipart: true, role: "form", class: "form-inline"}) do |f| %> | |
<% if @user_import.errors.any? %> | |
<div class="alert alert-danger"> | |
<ul> | |
<% @user_import.errors.full_messages.each do |msg| %> | |
<li><%= msg %></li> | |
<% end %> | |
</ul> | |
</div> | |
<% end %> | |
<div class="form-group"> | |
<%= f.file_field :file, class: "form-control" %> | |
</div> | |
<div class="form-group"> | |
<%= f.button "Upload", class: ["btn","btn-default"] %> | |
</div> | |
<% end %> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UserImport | |
CSV_OPTIONS = {encoding: 'UTF-8'}.freeze | |
include ActiveModel::Model | |
attr_accessor :file | |
validates :file, presence: true | |
validate :csv_format, if: Proc.new { |m| m.file.present? } | |
def save | |
return false unless valid? | |
User.transaction do | |
CSV.read(path, "r", CSV_OPTIONS).each_with_index do |row, index| | |
user = User.new(email: row[0], first_name: row[1], last_name: row[2]) | |
unless user.save | |
errors.add("line #{index+1} : ", user.errors.full_messages.join(" , ")) | |
end | |
end | |
if errors.any? | |
raise ActiveRecord::Rollback | |
end | |
end | |
!errors.any? | |
end | |
private | |
def csv_format | |
CSV.open(path, "r", CSV_OPTIONS) { |csv| } | |
rescue | |
errors.add(:file, "is invalid csv format") | |
end | |
def path | |
if file.respond_to? :path | |
file.path | |
else | |
file | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rails_helper" | |
RSpec.describe UserImport do | |
describe "#file" do | |
subject { UserImport.new(file: file) } | |
context "設定されていない時" do | |
let(:file) { nil } | |
it { expect(subject).to have(1).errors_on(:file) } | |
end | |
context "設定されている時" do | |
let(:file) { Rails.root.join("spec/fixtures/valid.csv") } | |
it { expect(subject).not_to have(1).errors_on(:file) } | |
end | |
context "有効なフォーマットの時" do | |
let(:file) { Rails.root.join("spec/fixtures/valid.csv") } | |
it { expect(subject).not_to have(1).errors_on(:file) } | |
end | |
context "無効なフォーマットの時" do | |
let(:file) { Rails.root.join("spec/fixtures/invalid.csv") } | |
it { expect(subject).to have(1).errors_on(:file) } | |
end | |
end | |
describe "#save" do | |
subject { UserImport.new(file: file) } | |
context "有効なフォーマットの時" do | |
let(:file) { Rails.root.join("spec/fixtures/valid.csv") } | |
let(:error_count) { CSV.read(file).count } | |
it { expect(subject.save).to be_truthy } | |
it { expect { subject.save }.to change(User, :count).by(error_count) } | |
end | |
context "無効なフォーマットの時" do | |
let(:file) { Rails.root.join("spec/fixtures/invalid.csv") } | |
it { expect(subject.save).to be_falsey } | |
end | |
context "Userモデルでエラーでがある時" do | |
let(:file) { Rails.root.join("spec/fixtures/valid.csv") } | |
let(:errors) { double(add: nil, clear: nil, empty?: nil) } | |
before do | |
allow_any_instance_of(User).to receive(:save) { false } | |
expect(subject).to receive(:errors) { errors }.twice | |
end | |
it { expect(subject.save).to be_falsey } | |
it { expect { subject.save }.not_to change(User, :count) } | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rails_helper" | |
RSpec.describe Admin::UsersController do | |
describe "GET index" do | |
before do | |
get :index | |
end | |
it { expect(assigns(:user_import)).to be_kind_of(UserImport) } | |
end | |
describe "POST import" do | |
let(:attributes) { { file: Rack::Test::UploadedFile.new(file, "text/plan") } } | |
describe "with valid params" do | |
let(:file) { Rails.root.join("spec/fixtures/valid.csv") } | |
let(:record_count) { CSV.read(file).count } | |
it "creates new Users" do | |
expect { | |
post :import, {user_import: attributes} | |
}.to change(User, :count).by(record_count) | |
end | |
it "redirects to the created user" do | |
post :import, {user_import: attributes} | |
expect(response).to redirect_to(action: :index) | |
end | |
end | |
describe "with invalid params" do | |
let(:file) { Rails.root.join("spec/fixtures/invalid.csv") } | |
it "do not creates new Users" do | |
expect { | |
post :import, {user_import: attributes} | |
}.not_to change(User, :count) | |
end | |
it "re-renders the 'index' template" do | |
post :import, {user: attributes} | |
expect(response).to render_template("index") | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Admin::UsersController < ApplicationController | |
def index | |
@user_import = UserImport.new | |
end | |
def import | |
@user_import = UserImport.new(params[:user_import]) | |
if @user_import.save | |
redirect_to url_for(action: :index), notice: 'Upload successful' | |
else | |
render :index | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment