20 changed files with 659 additions and 1 deletions
-
1Gemfile
-
4Gemfile.lock
-
2Rakefile
-
289app/assets/stylesheets/formtastic.css
-
59app/controllers/posts_controller.rb
-
2app/helpers/posts_helper.rb
-
2app/models/post.rb
-
5app/views/posts/_form.html.erb
-
2app/views/posts/_post.html.erb
-
10app/views/posts/edit.html.erb
-
43app/views/posts/index.html.erb
-
9app/views/posts/new.html.erb
-
15app/views/posts/show.html.erb
-
118config/initializers/formtastic.rb
-
1config/routes.rb
-
11db/migrate/20260303141001_create_posts.rb
-
21db/schema.rb
-
48test/controllers/posts_controller_test.rb
-
11test/fixtures/posts.yml
-
7test/models/post_test.rb
@ -1,6 +1,6 @@ |
|||
# Add your own tasks in files placed in lib/tasks ending in .rake, |
|||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. |
|||
|
|||
require_relative "config/application" |
|||
require_relative 'config/application' |
|||
|
|||
Rails.application.load_tasks |
|||
@ -0,0 +1,289 @@ |
|||
/* ------------------------------------------------------------------------------------------------- |
|||
|
|||
It's *strongly* suggested that you don't modify this file. Instead, load a new stylesheet after |
|||
this one in your layouts (eg formtastic_changes.css) and override the styles to suit your needs. |
|||
This will allow you to update formtastic.css with new releases without clobbering your own changes. |
|||
|
|||
This stylesheet forms part of the Formtastic Rails gem |
|||
(c) Justin French |
|||
|
|||
--------------------------------------------------------------------------------------------------*/ |
|||
|
|||
/* NORMALIZE AND RESET - obviously inspired by Yahoo's reset.css, but scoped to just .formtastic |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic, |
|||
.formtastic ul, |
|||
.formtastic ol, |
|||
.formtastic li, |
|||
.formtastic fieldset, |
|||
.formtastic legend, |
|||
.formtastic input, |
|||
.formtastic button, |
|||
.formtastic textarea, |
|||
.formtastic select, |
|||
.formtastic p { |
|||
margin:0; |
|||
padding:0; |
|||
} |
|||
|
|||
.formtastic fieldset { |
|||
border:0; |
|||
} |
|||
|
|||
.formtastic em, |
|||
.formtastic strong { |
|||
font-style:normal; |
|||
font-weight:normal; |
|||
} |
|||
|
|||
.formtastic ol, |
|||
.formtastic ul { |
|||
list-style:none; |
|||
} |
|||
|
|||
.formtastic abbr, |
|||
.formtastic acronym { |
|||
border:0; |
|||
font-variant:normal; |
|||
} |
|||
|
|||
.formtastic input, |
|||
.formtastic button, |
|||
.formtastic textarea { |
|||
font-family:sans-serif; |
|||
font-size:inherit; |
|||
font-weight:inherit; |
|||
} |
|||
|
|||
.formtastic input, |
|||
.formtastic textarea, |
|||
.formtastic select { |
|||
font-size:100%; |
|||
} |
|||
|
|||
.formtastic legend { |
|||
white-space:normal; |
|||
color:#000; |
|||
} |
|||
|
|||
|
|||
/* SEMANTIC ERRORS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .errors { |
|||
color:#cc0000; |
|||
margin:0.5em 0 1.5em 25%; |
|||
list-style:square; |
|||
} |
|||
|
|||
.formtastic .errors li { |
|||
padding:0; |
|||
border:none; |
|||
display:list-item; |
|||
} |
|||
|
|||
|
|||
/* BUTTONS & ACTIONS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .buttons, |
|||
.formtastic .actions { |
|||
overflow:hidden; /* clear containing floats */ |
|||
padding-left:25%; |
|||
} |
|||
|
|||
.formtastic .button, |
|||
.formtastic .action { |
|||
float:left; |
|||
padding-right:0.5em; |
|||
} |
|||
|
|||
.formtastic .button_action button { |
|||
padding:3px 8px; |
|||
} |
|||
|
|||
.formtastic .link_action a { |
|||
display:block; |
|||
padding:3px 0; |
|||
} |
|||
|
|||
|
|||
/* INPUTS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .inputs { |
|||
overflow:hidden; /* clear containing floats */ |
|||
} |
|||
|
|||
.formtastic .input { |
|||
overflow:hidden; /* clear containing floats */ |
|||
padding:0.5em 0; /* padding and negative margin juggling is for Firefox */ |
|||
margin-top:-0.5em; |
|||
margin-bottom:1em; |
|||
} |
|||
|
|||
|
|||
/* LEFT ALIGNED LABELS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .input .label { |
|||
display:block; |
|||
width:25%; |
|||
float:left; |
|||
padding-top:.2em; |
|||
} |
|||
|
|||
.formtastic .fragments .label, |
|||
.formtastic .choices .label { |
|||
position:absolute; |
|||
width:95%; |
|||
left:0px; |
|||
} |
|||
|
|||
.formtastic .fragments .label label, |
|||
.formtastic .choices .label label { |
|||
position:absolute; |
|||
} |
|||
|
|||
/* NESTED FIELDSETS AND LEGENDS (radio, check boxes and date/time inputs use nested fieldsets) |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .choices { |
|||
position:relative; |
|||
} |
|||
|
|||
.formtastic .choices-group { |
|||
float:left; |
|||
width:74%; |
|||
margin:0; |
|||
padding:0 0 0 25%; |
|||
} |
|||
|
|||
.formtastic .choice { |
|||
padding:0; |
|||
border:0; |
|||
} |
|||
|
|||
|
|||
/* INLINE HINTS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .input .inline-hints { |
|||
color:#666; |
|||
margin:0.5em 0 0 25%; |
|||
} |
|||
|
|||
|
|||
/* INLINE ERRORS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .inline-errors { |
|||
color:#cc0000; |
|||
margin:0.5em 0 0 25%; |
|||
} |
|||
|
|||
.formtastic .errors { |
|||
color:#cc0000; |
|||
margin:0.5em 0 0 25%; |
|||
list-style:square; |
|||
} |
|||
|
|||
.formtastic .errors li { |
|||
padding:0; |
|||
border:none; |
|||
display:list-item; |
|||
} |
|||
|
|||
|
|||
/* STRING, NUMERIC, PASSWORD, EMAIL, URL, PHONE, SEARCH (ETC) OVERRIDES |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .stringish input { |
|||
width:72%; |
|||
} |
|||
|
|||
.formtastic .stringish input[size], |
|||
.formtastic .stringish input[max] { |
|||
width:auto; |
|||
max-width:72%; |
|||
} |
|||
|
|||
|
|||
/* TEXTAREA OVERRIDES |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .text textarea { |
|||
width:72%; |
|||
} |
|||
|
|||
.formtastic .text textarea[cols] { |
|||
width:auto; |
|||
max-width:72%; |
|||
} |
|||
|
|||
|
|||
/* HIDDEN OVERRIDES |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .hidden { |
|||
display:none; |
|||
} |
|||
|
|||
|
|||
/* BOOLEAN LABELS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .boolean label { |
|||
margin-left:25%; |
|||
display:block; |
|||
} |
|||
|
|||
|
|||
/* CHOICE GROUPS |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .choices-group { |
|||
margin-bottom:-0.5em; |
|||
} |
|||
|
|||
.formtastic .choice { |
|||
margin:0.1em 0 0.5em 0; |
|||
} |
|||
|
|||
.formtastic .choice label { |
|||
float:none; |
|||
width:100%; |
|||
line-height:100%; |
|||
padding-top:0; |
|||
margin-bottom:0.6em; |
|||
} |
|||
|
|||
|
|||
/* ADJUSTMENTS FOR INPUTS INSIDE LABELS (boolean input, radio input, check_boxes input) |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .choice label input, |
|||
.formtastic .boolean label input { |
|||
margin:0 0.3em 0 0.1em; |
|||
line-height:100%; |
|||
} |
|||
|
|||
|
|||
/* FRAGMENTED INPUTS (DATE/TIME/DATETIME) |
|||
--------------------------------------------------------------------------------------------------*/ |
|||
.formtastic .fragments { |
|||
position:relative; |
|||
} |
|||
|
|||
.formtastic .fragments-group { |
|||
float:left; |
|||
width:74%; |
|||
margin:0; |
|||
padding:0 0 0 25%; |
|||
} |
|||
|
|||
.formtastic .fragment { |
|||
float:left; |
|||
width:auto; |
|||
margin:0 .3em 0 0; |
|||
padding:0; |
|||
border:0; |
|||
} |
|||
|
|||
.formtastic .fragment label { |
|||
display:none; |
|||
} |
|||
|
|||
.formtastic .fragment label input { |
|||
display:inline; |
|||
margin:0; |
|||
padding:0; |
|||
} |
|||
|
|||
@ -0,0 +1,59 @@ |
|||
class PostsController < ApplicationController |
|||
before_action :set_post, only: %i[show edit update destroy] |
|||
|
|||
# GET /posts |
|||
def index |
|||
@posts = Post.all |
|||
end |
|||
|
|||
# GET /posts/1 |
|||
def show |
|||
end |
|||
|
|||
# GET /posts/new |
|||
def new |
|||
@post = Post.new |
|||
end |
|||
|
|||
# GET /posts/1/edit |
|||
def edit |
|||
end |
|||
|
|||
# POST /posts |
|||
def create |
|||
@post = Post.new(post_params) |
|||
|
|||
if @post.save |
|||
redirect_to @post, notice: 'Post was successfully created.' |
|||
else |
|||
render :new, status: :unprocessable_content |
|||
end |
|||
end |
|||
|
|||
# PATCH/PUT /posts/1 |
|||
def update |
|||
if @post.update(post_params) |
|||
redirect_to @post, notice: 'Post was successfully updated.', status: :see_other |
|||
else |
|||
render :edit, status: :unprocessable_content |
|||
end |
|||
end |
|||
|
|||
# DELETE /posts/1 |
|||
def destroy |
|||
@post.destroy! |
|||
redirect_to posts_path, notice: 'Post was successfully destroyed.', status: :see_other |
|||
end |
|||
|
|||
private |
|||
|
|||
# Use callbacks to share common setup or constraints between actions. |
|||
def set_post |
|||
@post = Post.find(params.expect(:id)) |
|||
end |
|||
|
|||
# Only allow a list of trusted parameters through. |
|||
def post_params |
|||
params.require(:post).permit(:title, :quantity, :content) |
|||
end |
|||
end |
|||
@ -0,0 +1,2 @@ |
|||
module PostsHelper |
|||
end |
|||
@ -0,0 +1,2 @@ |
|||
class Post < ApplicationRecord |
|||
end |
|||
@ -0,0 +1,5 @@ |
|||
<%= semantic_form_for @post do |f| %> |
|||
<%= f.inputs %> |
|||
<%= f.semantic_errors :state %> |
|||
<%= f.actions %> |
|||
<% end %> |
|||
@ -0,0 +1,2 @@ |
|||
<div id="<%= dom_id post %>" class="w-full sm:w-auto my-5 space-y-5"> |
|||
</div> |
|||
@ -0,0 +1,10 @@ |
|||
<% content_for :title, "Editing post" %> |
|||
|
|||
<div class="md:w-2/3 w-full"> |
|||
<h1 class="font-bold text-4xl">Editing post</h1> |
|||
|
|||
<%= render "form", post: @post %> |
|||
|
|||
<%= link_to "Show this post", @post, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %> |
|||
<%= link_to "Back to posts", posts_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %> |
|||
</div> |
|||
@ -0,0 +1,43 @@ |
|||
<% content_for :title, "Posts" %> |
|||
|
|||
<div class="w-full"> |
|||
<% if notice.present? %> |
|||
<p |
|||
class=" |
|||
py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md |
|||
inline-block |
|||
" |
|||
id="notice" |
|||
> |
|||
<%= notice %> |
|||
</p> |
|||
<% end %> |
|||
|
|||
<div class="flex justify-between items-center"> |
|||
<h1 class="font-bold text-4xl">Posts</h1> |
|||
<%= link_to "New post", new_post_path, class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white block font-medium" %> |
|||
</div> |
|||
|
|||
<div id="posts" class="min-w-full divide-y divide-gray-200 space-y-5"> |
|||
<% if @posts.any? %> |
|||
<% @posts.each do |post| %> |
|||
<div |
|||
class=" |
|||
flex flex-col sm:flex-row justify-between items-center pb-5 |
|||
sm:pb-0 |
|||
" |
|||
> |
|||
<%= render post %> |
|||
|
|||
<div class="w-full sm:w-auto flex flex-col sm:flex-row space-x-2 space-y-2"> |
|||
<%= link_to "Show", post, class: "btn btn-primary" %> |
|||
<%= link_to "Edit", edit_post_path(post), class: "btn btn-secondary" %> |
|||
<%= button_to "Destroy", post, method: :delete, class: "btn btn-accent", data: { turbo_confirm: "Are you sure?" } %> |
|||
</div> |
|||
</div> |
|||
<% end %> |
|||
<% else %> |
|||
<p class="text-center my-10">No posts found.</p> |
|||
<% end %> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,9 @@ |
|||
<% content_for :title, "New post" %> |
|||
|
|||
<div class="md:w-2/3 w-full"> |
|||
<h1 class="font-bold text-4xl">New post</h1> |
|||
|
|||
<%= render "form", post: @post %> |
|||
|
|||
<%= link_to "Back to posts", posts_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %> |
|||
</div> |
|||
@ -0,0 +1,15 @@ |
|||
<% content_for :title, "Showing post" %> |
|||
|
|||
<div class="md:w-2/3 w-full"> |
|||
<% if notice.present? %> |
|||
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%= notice %></p> |
|||
<% end %> |
|||
|
|||
<h1 class="font-bold text-4xl">Showing post</h1> |
|||
|
|||
<%= render @post %> |
|||
|
|||
<%= link_to "Edit this post", edit_post_path(@post), class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %> |
|||
<%= link_to "Back to posts", posts_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %> |
|||
<%= button_to "Destroy this post", @post, method: :delete, form_class: "sm:inline-block mt-2 sm:mt-0 sm:ml-2", class: "w-full rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium cursor-pointer", data: { turbo_confirm: "Are you sure?" } %> |
|||
</div> |
|||
@ -0,0 +1,118 @@ |
|||
# frozen_string_literal: true |
|||
|
|||
# Set the default text field size when input is a string. Default is nil. |
|||
# Formtastic::FormBuilder.default_text_field_size = 50 |
|||
|
|||
# Set the default text area height when input is a text. Default is 20. |
|||
# Formtastic::FormBuilder.default_text_area_height = 5 |
|||
|
|||
# Set the default text area width when input is a text. Default is nil. |
|||
# Formtastic::FormBuilder.default_text_area_width = 50 |
|||
|
|||
# Should all fields be considered "required" by default? |
|||
# Defaults to true. |
|||
# Formtastic::FormBuilder.all_fields_required_by_default = true |
|||
|
|||
# Should select fields have a blank option/prompt by default? |
|||
# Defaults to true. |
|||
# Formtastic::FormBuilder.include_blank_for_select_by_default = true |
|||
|
|||
# Set the string that will be appended to the labels/fieldsets which are required. |
|||
# It accepts string or procs and the default is a localized version of |
|||
# '<abbr title="required">*</abbr>'. In other words, if you configure formtastic.required |
|||
# in your locale, it will replace the abbr title properly. But if you don't want to use |
|||
# abbr tag, you can simply give a string as below. |
|||
# Formtastic::FormBuilder.required_string = "(required)" |
|||
|
|||
# Set the string that will be appended to the labels/fieldsets which are optional. |
|||
# Defaults to an empty string ("") and also accepts procs (see required_string above). |
|||
# Formtastic::FormBuilder.optional_string = "(optional)" |
|||
|
|||
# Set the way inline errors will be displayed. |
|||
# Defaults to :sentence, valid options are :sentence, :list, :first and :none |
|||
# Formtastic::FormBuilder.inline_errors = :sentence |
|||
# Formtastic uses the following classes as default for hints, inline_errors and error list |
|||
|
|||
# If you override the class here, please ensure to override it in your stylesheets as well. |
|||
# Formtastic::FormBuilder.default_hint_class = "inline-hints" |
|||
# Formtastic::FormBuilder.default_inline_error_class = "inline-errors" |
|||
# Formtastic::FormBuilder.default_error_list_class = "errors" |
|||
|
|||
# Set the method to call on label text to transform or format it for human-friendly |
|||
# reading when formtastic is used without object. Defaults to :humanize. |
|||
# Formtastic::FormBuilder.label_str_method = :humanize |
|||
|
|||
# Set the array of methods to try calling on parent objects in :select and :radio inputs |
|||
# for the text inside each @<option>@ tag or alongside each radio @<input>@. The first method |
|||
# that is found on the object will be used. |
|||
# Defaults to ["to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"] |
|||
# Formtastic::FormBuilder.collection_label_methods = [ |
|||
# "to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"] |
|||
|
|||
# Specifies if labels/hints for input fields automatically be looked up using I18n. |
|||
# Default value: true. Overridden for specific fields by setting value to true, |
|||
# i.e. :label => true, or :hint => true (or opposite depending on initialized value) |
|||
# Formtastic::FormBuilder.i18n_lookups_by_default = false |
|||
|
|||
# Specifies if I18n lookups of the default I18n Localizer should be cached to improve performance. |
|||
# Defaults to true. |
|||
# Formtastic::FormBuilder.i18n_cache_lookups = false |
|||
|
|||
# Specifies the class to use for localization lookups. You can create your own |
|||
# class and use it instead by subclassing Formtastic::Localizer (which is the default). |
|||
# Formtastic::FormBuilder.i18n_localizer = MyOwnLocalizer |
|||
|
|||
# You can add custom inputs or override parts of Formtastic by subclassing Formtastic::FormBuilder and |
|||
# specifying that class here. Defaults to Formtastic::FormBuilder. |
|||
# Formtastic::Helpers::FormHelper.builder = MyCustomBuilder |
|||
|
|||
# All formtastic forms have a class that indicates that they are just that. You |
|||
# can change it to any class you want. |
|||
# Formtastic::Helpers::FormHelper.default_form_class = 'formtastic' |
|||
|
|||
# Formtastic will infer a class name from the model, array, string or symbol you pass to the |
|||
# form builder. You can customize the way that class is presented by overriding |
|||
# this proc. |
|||
# Formtastic::Helpers::FormHelper.default_form_model_class_proc = proc { |model_class_name| model_class_name } |
|||
|
|||
# Allows to set a custom field_error_proc wrapper. By default this wrapper |
|||
# is disabled since `formtastic` already adds an error class to the LI tag |
|||
# containing the input. |
|||
# Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc { |html_tag, instance_tag| html_tag } |
|||
|
|||
# You can opt-in to Formtastic's use of the HTML5 `required` attribute on `<input>`, `<select>` |
|||
# and `<textarea>` tags by setting this to true (defaults to false). |
|||
# Formtastic::FormBuilder.use_required_attribute = false |
|||
|
|||
# You can opt-in to new HTML5 browser validations (for things like email and url inputs) by setting |
|||
# this to true. Doing so will omit the `novalidate` attribute from the `<form>` tag. |
|||
# See http://diveintohtml5.org/forms.html#validation for more info. |
|||
# Formtastic::FormBuilder.perform_browser_validations = true |
|||
|
|||
# By creating custom input class finder, you can change how input classes are looked up. |
|||
# For example you can make it to search for TextInputFilter instead of TextInput. |
|||
# See https://github.com/formtastic/formtastic/wiki/Custom-Class-Finders |
|||
# Formtastic::FormBuilder.input_class_finder = Formtastic::InputClassFinder |
|||
|
|||
# Define custom namespaces in which to look up your Input classes. Default is |
|||
# to look up in the global scope and in Formtastic::Inputs. |
|||
# Formtastic::FormBuilder.input_namespaces = [ ::Object, ::MyInputsModule, ::Formtastic::Inputs ] |
|||
|
|||
# By creating custom action class finder, you can change how action classes are looked up. |
|||
# For example you can make it to search for MyButtonAction instead of ButtonAction. |
|||
# See https://github.com/formtastic/formtastic/wiki/Custom-Class-Finders |
|||
# Formtastic::FormBuilder.action_class_finder = Formtastic::ActionClassFinder |
|||
|
|||
# Define custom namespaces in which to look up your Action classes. Default is |
|||
# to look up in the global scope and in Formtastic::Actions. |
|||
# Formtastic::FormBuilder.action_namespaces = [ ::Object, ::MyActionsModule, ::Formtastic::Actions ] |
|||
|
|||
# Which columns to skip when automatically rendering a form without any fields specified. |
|||
# Formtastic::FormBuilder.skipped_columns = [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version] |
|||
|
|||
# You can opt-in to accessibility features for the `semantic_errors` helper by setting |
|||
# this to true. Doing so will render the attributes in the error summary list |
|||
# as `<li> <a>` links to the inputs that have errors. the inline error sentence's id is added to |
|||
# the errored input's aria-describedby. This ensures that the errored input is read out with |
|||
# the inline error sentence's error explanation, aria-invalid is set to true for errored inputs |
|||
# Formtastic::FormBuilder.semantic_errors_link_to_inputs = true |
|||
@ -0,0 +1,11 @@ |
|||
class CreatePosts < ActiveRecord::Migration[8.1] |
|||
def change |
|||
create_table :posts do |t| |
|||
t.string :title |
|||
t.integer :quantity |
|||
t.string :content |
|||
|
|||
t.timestamps |
|||
end |
|||
end |
|||
end |
|||
@ -0,0 +1,21 @@ |
|||
# This file is auto-generated from the current state of the database. Instead |
|||
# of editing this file, please use the migrations feature of Active Record to |
|||
# incrementally modify your database, and then regenerate this schema definition. |
|||
# |
|||
# This file is the source Rails uses to define your schema when running `bin/rails |
|||
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to |
|||
# be faster and is potentially less error prone than running all of your |
|||
# migrations from scratch. Old migrations may fail to apply correctly if those |
|||
# migrations use external dependencies or application code. |
|||
# |
|||
# It's strongly recommended that you check this file into your version control system. |
|||
|
|||
ActiveRecord::Schema[8.1].define(version: 2026_03_03_141001) do |
|||
create_table "posts", force: :cascade do |t| |
|||
t.string "content" |
|||
t.datetime "created_at", null: false |
|||
t.integer "quantity" |
|||
t.string "title" |
|||
t.datetime "updated_at", null: false |
|||
end |
|||
end |
|||
@ -0,0 +1,48 @@ |
|||
require "test_helper" |
|||
|
|||
class PostsControllerTest < ActionDispatch::IntegrationTest |
|||
setup do |
|||
@post = posts(:one) |
|||
end |
|||
|
|||
test "should get index" do |
|||
get posts_url |
|||
assert_response :success |
|||
end |
|||
|
|||
test "should get new" do |
|||
get new_post_url |
|||
assert_response :success |
|||
end |
|||
|
|||
test "should create post" do |
|||
assert_difference("Post.count") do |
|||
post posts_url, params: { post: {} } |
|||
end |
|||
|
|||
assert_redirected_to post_url(Post.last) |
|||
end |
|||
|
|||
test "should show post" do |
|||
get post_url(@post) |
|||
assert_response :success |
|||
end |
|||
|
|||
test "should get edit" do |
|||
get edit_post_url(@post) |
|||
assert_response :success |
|||
end |
|||
|
|||
test "should update post" do |
|||
patch post_url(@post), params: { post: {} } |
|||
assert_redirected_to post_url(@post) |
|||
end |
|||
|
|||
test "should destroy post" do |
|||
assert_difference("Post.count", -1) do |
|||
delete post_url(@post) |
|||
end |
|||
|
|||
assert_redirected_to posts_url |
|||
end |
|||
end |
|||
@ -0,0 +1,11 @@ |
|||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html |
|||
|
|||
one: |
|||
title: MyString |
|||
quantity: 1 |
|||
content: MyString |
|||
|
|||
two: |
|||
title: MyString |
|||
quantity: 1 |
|||
content: MyString |
|||
@ -0,0 +1,7 @@ |
|||
require "test_helper" |
|||
|
|||
class PostTest < ActiveSupport::TestCase |
|||
# test "the truth" do |
|||
# assert true |
|||
# end |
|||
end |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue