Rails 7 Vanilla-Nest-Nest Gem链接添加项目不起作用
我正在尝试使用带有Rails 7的香草巢宝石,以嵌套编辑形式添加一个项目。该链接不起作用,也不是行动结果。
我试图在Rails 7的GEM测试路径中遵循示例代码。
这是编辑视图:
Activity/edit.html.erb
<div class="container">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<br>
<h1 class="m-0 text-dark">Update Transaction</h1>
</div>
</div>
</div>
</div>
<%= render "form", activity: @activity %>
表单部分:
active/_form.html.erb
<div class="row no-gutters">
<div class="col-auto">
<%= image_tag '16419114852474091540459891939039.jpeg', class: "main-image",
width: "658", sizes: "(max-width: 767px) 96vw, (max-width: 991px) 354px, 460px", alt: ""
%>
</div>
<div class="col">
<div class="card-block px-2">
<%= form_for activity do |form| %>
<div class="row">
<%= form.label :date_submitted, class: 'col-lg-3 text-right', style: "display: block" %>
<div class="col-lg-2">
<%= form.date_field :date_submitted %>
</div>
</div>
<br>
<div class="row">
<%= form.label :transaction_date, class: 'control-label col-lg-3', style: "display: block" %>
<div class="col-lg-2">
<%= form.date_field :activity_date %>
</div>
</div>
<br>
<div>
<div class="row">
<div class="col-lg-8">
<h3>Transaction Items</h3>
<%= link_to_add_nested(form, :items, '#items') do %>
<span><span> Add Item</span></span>
<% end %>
</div>
</div>
<div id='items'>
<%= form.fields_for :items do |sub_form| %>
<%= render 'item_fields', form: sub_form %>
<% end %>
</div>
</div>
<div>
<%= form.submit 'Save Update', class: "btn btn-primary" %>
</div>
<% end %>
<br>
</div>
</div>
</div>
<div class="card-footer w-100 text-muted">
<div>
<%= link_to "Show this activity", @activity %> |
<%= link_to "Back to activities", activities_path %>
</div>
</div>
字段部分:
Activity/_item_fields.html 。
<div class="item-fields">
<div class="row">
<div class="col-lg-6">
<%= form.label :amount, style: "display: block" %>
<%= form.text_field :item_amount %>
</div>
<div class="col-lg-4">
<%= form.label :vendor, style: "display: block" %>
<%= form.text_field :vendor %>
</div>
</div>
<br>
<div class="row">
<div class="col-lg-6">
<%= form.label :expense_category, style: "display: block" %>
<%= form.select(:expense_category, @category_choices) %>
</div>
<div class="col-lg-4">
<%= form.label :transaction_type, style: "display: block" %>
<%= form.select(:transaction_type, @transaction_choices) %>
</div>
</div>
<br>
</div>
class Item < ApplicationRecord
belongs_to :activity
end
class Activity < ApplicationRecord
belongs_to :account
belongs_to :user
has_many :items, dependent: :destroy
accepts_nested_attributes_for :items, reject_if: :all_blank
has_one_attached :activity_image
validate :acceptable_image
def acceptable_image
return unless activity_image.attached?
unless activity_image.byte_size <= 5.megabyte
errors.add(:activity_image, "is too big")
end
acceptable_types = ["image/jpeg", "image/png"]
unless acceptable_types.include?(activity_image.content_type)
errors.add(:activity_image, "must be a JPEG or PNG")
end
end
end
class ActivitiesController < ApplicationController
before_action :set_activity, only: %i[ show edit update destroy add_item ]
# GET /activities or /activities.json
def index
@activities = Activity.all
end
# GET /activities/1 or /activities/1.json
def show
end
# GET /activities/new
def new
@activity = Activity.new
@activity.items.build
end
# GET /activities/1/edit
def edit
set_transaction_choices
set_category_choices
end
# POST /activities or /activities.json
def create
@activity = Activity.new(activity_params)
respond_to do |format|
if @activity.save
format.html { redirect_to activity_url(@activity), notice: "Activity was successfully created." }
format.json { render :show, status: :created, location: @activity }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @activity.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /activities/1 or /activities/1.json
def update
respond_to do |format|
if @activity.update(activity_params)
format.html { redirect_to activity_url(@activity), notice: "Activity was successfully updated." }
format.json { render :show, status: :ok, location: @activity }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @activity.errors, status: :unprocessable_entity }
end
end
end
# DELETE /activities/1 or /activities/1.json
def destroy
@activity.destroy
respond_to do |format|
format.html { redirect_to activities_url, notice: "Activity was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_activity
@activity = Activity.find(params[:id])
end
# Only allow a list of trusted parameters through.
def activity_params
params.require(:activity).permit(:account_id, :user_id, :date_submitted,
:activity_date, :reviewed, :finalized, :notes, :emailed_question,
items_attributes: [ :id, :item_amount, :vendor,
:expense_category, :transaction_type])
end
def set_transaction_choices
@transaction_choices = [["Expense", 'expense'], ["Revenue", 'revenue']]
end
def set_category_choices
@category_choices = ['Fuel', 'Tolls',
'Repairs and Maintance', 'Plates', 'Truck Insurance',
'Cell Phone', 'Internet', 'Satellite', 'Perdiem Days',
'Office Supplies', 'Professional Services',
'Other expenses', 'Liability Insurnace', 'Health Insurnace',
'Truck Supplies and Equipment',
'Working Clothes and Gear', 'Lease and Rental Fees',
'Taxes and Licenses', 'Travel Expenses',
'Contract Wages', 'Revenue',
'Marketing Fees', 'Subscriptions',
'Software' ]
@category_choices.sort!
end
end
class ItemsController < ApplicationController
before_action :set_item, only: %i[ show edit update destroy ]
# GET /items or /items.json
def index
@items = Item.all
end
# GET /items/1 or /items/1.json
def show
end
# GET /items/new
def new
end
# GET /items/1/edit
def edit
end
def add_item
@act = Activity.find(params[:activity_id])
@act.items.create(
activity: @act
)
end
# POST /items or /items.json
# POST /items or /items.json
def create
@item = Item.new(item_params)
respond_to do |format|
if @item.save
format.html { redirect_to edit_activity_path(activity_id), notice: "Item was successfully created." }
#format.json { render :show, status: :created, location: @item }
else
format.html { render :new, status: :unprocessable_entity }
#format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1 or /items/1.json
def update
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to item_url(@item), notice: "Item was successfully updated." }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1 or /items/1.json
def destroy
@item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: "Item was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
# Only allow a list of trusted parameters through.
def item_params
params.require(:item).permit(:activity_id, :item_amount, :vendor, :expense_category, :transaction_type)
end
end
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"
import * as bootstrap from "bootstrap"
import "custom/main"
import "vanilla-nested";
.rb
config/importmap.rb
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "vanilla-nested", to: "vanilla_nested.js", preload: true
pin_all_from "app/javascript/custom", under: "custom"
I am trying to use the vanilla-nested gem, with Rails 7, to add an item in a nested edit form. The link is not work and not action results.
I have tried to follow the example code in the gem test path for rails 7.
Here is the edit view:
activities/edit.html.erb
<div class="container">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<br>
<h1 class="m-0 text-dark">Update Transaction</h1>
</div>
</div>
</div>
</div>
<%= render "form", activity: @activity %>
The form partial:
activities/_form.html.erb
<div class="row no-gutters">
<div class="col-auto">
<%= image_tag '16419114852474091540459891939039.jpeg', class: "main-image",
width: "658", sizes: "(max-width: 767px) 96vw, (max-width: 991px) 354px, 460px", alt: ""
%>
</div>
<div class="col">
<div class="card-block px-2">
<%= form_for activity do |form| %>
<div class="row">
<%= form.label :date_submitted, class: 'col-lg-3 text-right', style: "display: block" %>
<div class="col-lg-2">
<%= form.date_field :date_submitted %>
</div>
</div>
<br>
<div class="row">
<%= form.label :transaction_date, class: 'control-label col-lg-3', style: "display: block" %>
<div class="col-lg-2">
<%= form.date_field :activity_date %>
</div>
</div>
<br>
<div>
<div class="row">
<div class="col-lg-8">
<h3>Transaction Items</h3>
<%= link_to_add_nested(form, :items, '#items') do %>
<span><span> Add Item</span></span>
<% end %>
</div>
</div>
<div id='items'>
<%= form.fields_for :items do |sub_form| %>
<%= render 'item_fields', form: sub_form %>
<% end %>
</div>
</div>
<div>
<%= form.submit 'Save Update', class: "btn btn-primary" %>
</div>
<% end %>
<br>
</div>
</div>
</div>
<div class="card-footer w-100 text-muted">
<div>
<%= link_to "Show this activity", @activity %> |
<%= link_to "Back to activities", activities_path %>
</div>
</div>
The fields partial:
activities/_item_fields.html.erb
<div class="item-fields">
<div class="row">
<div class="col-lg-6">
<%= form.label :amount, style: "display: block" %>
<%= form.text_field :item_amount %>
</div>
<div class="col-lg-4">
<%= form.label :vendor, style: "display: block" %>
<%= form.text_field :vendor %>
</div>
</div>
<br>
<div class="row">
<div class="col-lg-6">
<%= form.label :expense_category, style: "display: block" %>
<%= form.select(:expense_category, @category_choices) %>
</div>
<div class="col-lg-4">
<%= form.label :transaction_type, style: "display: block" %>
<%= form.select(:transaction_type, @transaction_choices) %>
</div>
</div>
<br>
</div>
The Items model
models/item.rb
class Item < ApplicationRecord
belongs_to :activity
end
The Activity model:
models/activity.rb
class Activity < ApplicationRecord
belongs_to :account
belongs_to :user
has_many :items, dependent: :destroy
accepts_nested_attributes_for :items, reject_if: :all_blank
has_one_attached :activity_image
validate :acceptable_image
def acceptable_image
return unless activity_image.attached?
unless activity_image.byte_size <= 5.megabyte
errors.add(:activity_image, "is too big")
end
acceptable_types = ["image/jpeg", "image/png"]
unless acceptable_types.include?(activity_image.content_type)
errors.add(:activity_image, "must be a JPEG or PNG")
end
end
end
The Activities controller
controllers/activities_controller.rb
class ActivitiesController < ApplicationController
before_action :set_activity, only: %i[ show edit update destroy add_item ]
# GET /activities or /activities.json
def index
@activities = Activity.all
end
# GET /activities/1 or /activities/1.json
def show
end
# GET /activities/new
def new
@activity = Activity.new
@activity.items.build
end
# GET /activities/1/edit
def edit
set_transaction_choices
set_category_choices
end
# POST /activities or /activities.json
def create
@activity = Activity.new(activity_params)
respond_to do |format|
if @activity.save
format.html { redirect_to activity_url(@activity), notice: "Activity was successfully created." }
format.json { render :show, status: :created, location: @activity }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @activity.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /activities/1 or /activities/1.json
def update
respond_to do |format|
if @activity.update(activity_params)
format.html { redirect_to activity_url(@activity), notice: "Activity was successfully updated." }
format.json { render :show, status: :ok, location: @activity }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @activity.errors, status: :unprocessable_entity }
end
end
end
# DELETE /activities/1 or /activities/1.json
def destroy
@activity.destroy
respond_to do |format|
format.html { redirect_to activities_url, notice: "Activity was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_activity
@activity = Activity.find(params[:id])
end
# Only allow a list of trusted parameters through.
def activity_params
params.require(:activity).permit(:account_id, :user_id, :date_submitted,
:activity_date, :reviewed, :finalized, :notes, :emailed_question,
items_attributes: [ :id, :item_amount, :vendor,
:expense_category, :transaction_type])
end
def set_transaction_choices
@transaction_choices = [["Expense", 'expense'], ["Revenue", 'revenue']]
end
def set_category_choices
@category_choices = ['Fuel', 'Tolls',
'Repairs and Maintance', 'Plates', 'Truck Insurance',
'Cell Phone', 'Internet', 'Satellite', 'Perdiem Days',
'Office Supplies', 'Professional Services',
'Other expenses', 'Liability Insurnace', 'Health Insurnace',
'Truck Supplies and Equipment',
'Working Clothes and Gear', 'Lease and Rental Fees',
'Taxes and Licenses', 'Travel Expenses',
'Contract Wages', 'Revenue',
'Marketing Fees', 'Subscriptions',
'Software' ]
@category_choices.sort!
end
end
The Items controller
controllers/items_controller.rb
class ItemsController < ApplicationController
before_action :set_item, only: %i[ show edit update destroy ]
# GET /items or /items.json
def index
@items = Item.all
end
# GET /items/1 or /items/1.json
def show
end
# GET /items/new
def new
end
# GET /items/1/edit
def edit
end
def add_item
@act = Activity.find(params[:activity_id])
@act.items.create(
activity: @act
)
end
# POST /items or /items.json
# POST /items or /items.json
def create
@item = Item.new(item_params)
respond_to do |format|
if @item.save
format.html { redirect_to edit_activity_path(activity_id), notice: "Item was successfully created." }
#format.json { render :show, status: :created, location: @item }
else
format.html { render :new, status: :unprocessable_entity }
#format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1 or /items/1.json
def update
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to item_url(@item), notice: "Item was successfully updated." }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1 or /items/1.json
def destroy
@item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: "Item was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
# Only allow a list of trusted parameters through.
def item_params
params.require(:item).permit(:activity_id, :item_amount, :vendor, :expense_category, :transaction_type)
end
end
The application.js file:
app/javascript/application.js
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"
import * as bootstrap from "bootstrap"
import "custom/main"
import "vanilla-nested";
the importmap.rb
config/importmap.rb
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "vanilla-nested", to: "vanilla_nested.js", preload: true
pin_all_from "app/javascript/custom", under: "custom"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论