【问题标题】:Rails nested routes for create method smart_listing用于创建方法 smart_listing 的 Rails 嵌套路由
【发布时间】:2016-05-22 02:09:20
【问题描述】:

我有两个模型:公寓和房间。公寓有_很多房间,房间属于_公寓。我使用 smart_listing gem 作为 ajax 形式。我在 edit_apartment_path 中显示我的表

= render 'rooms/index' # index is partial

然后我将它添加到我的 apartment_controller

def edit
    @rooms = smart_listing_create :rooms,
                                      Room.where(apartment_id: params[:apartment_id]),
                                      partial: "rooms/list"
end

现在我必须为我的表单设置路径

= simple_form_for object, url: object.new_record? ? apartment_rooms_path : apartment_room_path(id: object),
                   remote: true, html: {class: "form-horizontal"} do |f|
  = f.input :title
  = f.button :submit

我可以编辑我创建的房间,但我不能在公寓中创建新房间。我的错误:

ActionController::UrlGenerationError - No route matches {:action=>"edit", :apartment_id=>nil, :controller=>"rooms", :id=>#<Room id: 83, title: "dawawd">, created_at: "2016-02-11 10:36:30", updated_at: "2016-02-11 10:36:30", apartment_id: 4>} missing required keys: [:apartment_id]:

我的路线

resources :apartments do
      resources :rooms
    end

可能 smart_listing 不支持嵌套路由。有人知道吗? :)

【问题讨论】:

    标签: ruby-on-rails ruby forms routes


    【解决方案1】:

    这里是带有 smart_listing 的嵌套路由的简单示例。我认为这应该涵盖这个主题。 我用过Rails 4.2ruby 2.2.0smart_listing 1.1.2

    config/routes.rb

    resources :users do
      resources :bios
    end
    root 'users#index'
    

    models/user.rb

    class User < ActiveRecord::Base
      has_one :bio
      accepts_nested_attributes_for :bio, allow_destroy: true
      scope :like, ->(args) { where("email like '%#{args}%' OR name like '%#{args}%' OR surname like '%#{args}%'")}
    end
    

    models/bio.rb

    class Bio < ActiveRecord::Base
      belongs_to :user
    end
    

    controllers/users_controller.rb

    class UsersController < ApplicationController
      include SmartListing::Helper::ControllerExtensions
      helper  SmartListing::Helper
      before_action :set_user, only: [:update, :destroy]
    
      def index
        users_scope = User.all.includes(:bio)
        users_scope = users_scope.like(params[:filter]) if params[:filter]
        # @users = smart_listing_create :users, users_scope, partial: "users/list", page_sizes: [5, 7, 13, 26]
        @users = smart_listing_create(:users, users_scope, partial: 'users/list',
                                   sort_attributes: [
                                    [:name, 'name'],
                                    [:surname, 'surname'],
                                    [:email, 'email'],
                                    [:city, 'bio.city'],
                                    [:birthday, 'bio.birthday']
                                   ],
                                   default_sort: { start_at: 'desc' }
                                   )
      end
    
      def new
        @user = User.new
        @user.build_bio
      end
    
      def create
        @user = User.new(user_params)
        @user.save
      end
    
      def edit
        @user = User.includes(:bio).find(params[:id])
        @user.bio.build if @user.bio.nil?
      end
    
      def update
        @user.update(user_params)
      end
    
      def delete
      end
    
      def destroy
        @user.destroy
      end
    
      private
    
      def set_user
        @user = User.find(params[:id])
      end
    
      def user_params
        params.require(:user).permit(:name, :surname, :email, :bio_attributes => [:birthday, :city])
      end
    end
    

    views/users/index.html.haml

    = smart_listing_controls_for(:users, {class: "form-inline text-right"}) do
      .form-group.filter.input-append
        = text_field_tag :filter, '', class: "search form-control", 
                              placeholder: "Search...", autocomplete: :off
    = smart_listing_render :users
    

    views/users/_list.html.haml

    - unless smart_listing.empty?
      %table.table.table-striped
        %thead
          %th= smart_listing.sortable "Name", :name
          %th= smart_listing.sortable "Surname", :surname
          %th= smart_listing.sortable "Email", :email
          %th= smart_listing.sortable "City", :city
          %th= smart_listing.sortable "Birthday", :birthday
        %tbody
          - smart_listing.collection.each do |o|
            %tr.editable{data: {id: o.id}}
              = smart_listing.render object: o, partial: "users/user", locals: {object: o}
          = smart_listing.item_new colspan: 6, link: new_user_path
      = smart_listing.paginate
      = smart_listing.pagination_per_page_links
    - else
      %p.warning No users
    

    views/users/_user.html.haml

    %td= object.name
    %td= object.surname
    %td= object.email
    %td= object.bio.city
    %td= object.bio.birthday
    %td.actions= smart_listing_item_actions [ {name: :edit, url: edit_user_path(object)}, {name: :destroy, url: user_path(object), confirmation: "Are you sure you want to delete this?"}]
    

    views/users/_form.html.haml

    %td{colspan: 6}
      = form_for object, url: object.new_record? ? users_path : user_path(object), 
                     remote: true, html: {class: "form-horizontal"} do |f|
        %p
          Name: 
          = f.text_field :name
        %p
          Surname: 
          = f.text_field :surname
        %p
          Email: 
          = f.text_field :email
    
        = f.fields_for :bio do |ff|
          %p
            Birthday
            = ff.date_field :birthday
          %p
            City
            = ff.text_field :city
    
        = f.submit "Save", class: "btn btn-primary"
        %button.btn.btn-link.cancel Cancel
    

    views/users/create.js.erb

    <%= smart_listing_item :users, :create, @user, @user.persisted? ? "users/user" : "users/form" %>
    

    views/users/edit.js.erb

    <%= smart_listing_item :users, :edit, @user, "users/form" %>
    

    views/users/destroy.js.erb

    <%= smart_listing_item :users, :destroy, @user %>
    

    views/users/index.js.erb

    <%= smart_listing_update(:users) %>
    

    views/users/new.js.erb

    <%= smart_listing_item :users, :new, @user, "users/form" %>
    

    views/users/update.js.erb

    <%= smart_listing_item :users, :update, @user, @user.valid? ? "users/user" : "users/form" %>
    

    【讨论】:

    • 美丽的例子:) !!
    • 这有帮助吗?你让它在你的应用中工作了吗?
    【解决方案2】:

    您也应该收到@apartment 的表单,在这种情况下,如果您的@room.persisted? 表单收到编辑请求,否则创建:

    = simple_form_for [@apartment, @room], remote: true, html: {class: "form-horizontal"} do |f|
      = f.input :title
      = f.button :submit
    

    【讨论】:

    • 我测试了表单,当我创建新对象时,它成功在数据库中创建了项目,但是 smart_listing gem 的路由有问题。为什么它在我的数据库中成功创建项目并返回一些错误的路由?
    • 看看控制台日志,你更新对象的时候有什么路由?
    • ActionController::UrlGenerationError - No route matches {:action=&gt;"edit", :apartment_id=&gt;nil, :controller=&gt;"rooms", :id=&gt;#&lt;Room id: 83, title: "dawawd"&gt;, created_at: "2016-02-11 10:36:30", updated_at: "2016-02-11 10:36:30", apartment_id: 4&gt;} missing required keys: [:apartment_id]: 一样,但是在db中成功创建了item。也许我的 smart_listing 的 create.js.erb 文件是错误的:/
    • 但是如何在这段代码中发送参数? &lt;%= smart_listing_item :rooms, :create, @room, @room.valid? ? "rooms/room" : "rooms/form" %&gt; 当我手动添加参数时出现错误:undefined method 'persisted?'
    猜你喜欢
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2020-06-10
    • 1970-01-01
    相关资源
    最近更新 更多