【问题标题】:Ruby on Rails: render form on a shared folderRuby on Rails:在共享文件夹上呈现表单
【发布时间】:2018-07-29 22:17:17
【问题描述】:

我想将表单放在一个共享文件夹中以干燥代码并为 [:admin, :posts] 和 :posts 呈现此表单。 所以我创建了一个文件夹并将表单放在app/views/shared/_form.html.slim

- if params[:admin][:posts]
  post = [:admin, @post]
- if params[:posts]
  post = @post

= simple_form_for(post, :html => { :multipart => true }) do |f|
   = f.association :categories, label: "Select the Categories:", as: :check_boxes , collection: @categories.map{|c| [c.name, c.id]}, include_hidden: false
   = f.input :title
   = f.input :subtitle
   - if @post.attachment.present?
     .attachment
       p
         = image_tag(@post.attachment.thumb.url, alt: 'Image', class: "img-responsive img-thumbnail")
         = f.check_box :remove_attachment
         | Remove image
         br
          .text-center
            small
              sample
                = "File_size #{number_to_human_size(@post.attachment.size)}"
   = f.input :attachment, as: :file, label: "File"
   = f.input :attachment_cache, as: :hidden
   = f.input :remote_attachment_url, label: "Enter URL to an image"
   = f.input :content, size: "150x150"

   = f.button :submit, class: 'btn-primary'

然后继续

app/views/admin/post/new.html.slimapp/views/posts/edit.html.slim

我添加了渲染:

== render 'shared/form', post: @post

所以我尝试运行,我有这个错误:

ActionView::Template::Error (undefined method `[]' for nil:NilClass):
    1: - if params[:admin][:posts]
    2:   post = [:admin, @post]
    3: - if params[:posts]
    4:   post = @post

这只是我的一个想法。在这种情况下可以这样做还是忘记这样做?

路线:

rake routes | grep post
Running via Spring preloader in process 2187
             admin_posts POST   /admin/posts(.:format)                   admin/posts#create
          new_admin_post GET    /admin/posts/new(.:format)               admin/posts#new
              admin_post DELETE /admin/posts/:id(.:format)               admin/posts#destroy
nullify_posts_admin_user PATCH  /admin/users/:id/nullify_posts(.:format) admin/users#nullify_posts
                    root GET    /                                        posts#index
         published_posts GET    /posts/published(.:format)               posts#published
             draft_posts GET    /posts/draft(.:format)                   posts#draft
            recent_posts GET    /posts/recent(.:format)                  posts#recent
            publish_post PATCH  /posts/:id/publish(.:format)             posts#publish
          unpublish_post PATCH  /posts/:id/unpublish(.:format)           posts#unpublish
                   posts GET    /posts(.:format)                         posts#index
               edit_post GET    /posts/:id/edit(.:format)                posts#edit
                    post GET    /posts/:id(.:format)                     posts#show
                         PATCH  /posts/:id(.:format)                     posts#update
                         PUT    /posts/:id(.:format)                     posts#update

【问题讨论】:

  • params[:admin] 返回nil,因此[:posts] 引发错误。您可以将其更改为- if params[:admin] && params[:admin][:posts],但由于您将本地post 传递给部分设置,因此它再次没有多大意义。我想你可以把这个 == render 'shared/form', post: @post 改成 == render 'shared/form', post: params[:admin] && params[:admin][:posts] ? [:admin,@post] : @post 虽然我仍然不喜欢这种风格,但如果没有更好地理解实现,我不确定我能提出更好的解决方案
  • 这是因为目前在此应用程序上,管理员是唯一可以创建帖子的人。然后其他有角色的人可以编辑。
  • 我尝试了这个并显示了表单,但在新操作上创建不起作用并且操作编辑工作正常。错误是:No route matches [POST] "/posts"。感谢您的帮助@engineersmnky!
  • 我们可以看看你的 route.rb 关于 post 和 admin 的部分吗?
  • 我不知道为什么会发生这种情况,在我尝试使用共享的 DRY 之前。它工作正常。感谢@Poilon 的回复。我编辑问题并将路线放在那里。

标签: ruby-on-rails ruby ruby-on-rails-4 render


【解决方案1】:

我看到你想要做的是弄清楚你是在管理部分还是标准帖子部分,并以这种方式更改表单的 url。

这有点不标准。 一般来说,我看到的是只有表单的主体在共享表单部分,但动作保存在外部部分,所以例如:

app/views/admin/post/new.html.slim:

= simple_form_for(post, :html => { :multipart => true }) do |f|
  == render 'shared/post_form', f: f, post: post

app/views/shared/_post_form.html.slim:

   = f.association :categories, label: "Select the Categories:", as: :check_boxes , collection: @categories.map{|c| [c.name, c.id]}, include_hidden: false
   = f.input :title
   = f.input :subtitle
   - if post.attachment.present?
     .attachment
       p
         = image_tag(post.attachment.thumb.url, alt: 'Image', class: "img-responsive img-thumbnail")
         = f.check_box :remove_attachment
         | Remove image
         br
          .text-center
            small
              sample
                = "File_size #{number_to_human_size(post.attachment.size)}"
   = f.input :attachment, as: :file, label: "File"
   = f.input :attachment_cache, as: :hidden
   = f.input :remote_attachment_url, label: "Enter URL to an image"
   = f.input :content, size: "150x150"

   = f.button :submit, class: 'btn-primary'

注意:如果您将post 作为局部变量传递到表单中,则应将其与post 而非@post 一起使用(因为@post 完全忽略了您传入的局部变量并返回到任何传入的变量来自控制器,在这种情况下为什么还要传入局部变量?) 您也应该永远不要在模板中调用另一个变量 post... 因为它会覆盖旧的 post 变量然后消失。将其命名为不同的名称,例如在这种情况下,如果您真的想按照以前的方式使用模板,您可以将其命名为 post_url_params

【讨论】:

  • 谢谢@Taryn East。你的想法奏效了。我忘记使用这些积木了。
【解决方案2】:

所以按照@Taryn East 的想法,我把这个和工作的:

app/views/admin/posts/new.html.slim

= title("New Post")
.header
  h1 New Post

== render 'form', post: @post

app/views/admin/posts/edit.html.slim

= title("Edit Post", @post.title)

.header
  h1 Edit Post

== render "form", post: @post

app/views/admin/posts/_form.html.slim

= simple_form_for([:admin, post], :html => { :multipart => true }) do |f|
  == render "shared/post_form", f: f, post: post

app/views/posts/_form.html.slim

= simple_form_for(post, :html => { :multipart => true }) do |f|
  == render "shared/post_form", f: f, post: post

app/shared/_post_form.html.slim

= f.association :categories, label: "Select the Categories:", as: :check_boxes , collection: @categories.map{|c| [c.name, c.id]}, include_hidden: false
= f.input :title
= f.input :subtitle
- if post.attachment.present?
  .attachment
    p
      = image_tag(post.attachment.thumb.url, alt: 'Image', class: "img-responsive img-thumbnail")
      = f.check_box :remove_attachment
      | Remove image
      br
       .text-center
         small
           sample
             = "File_size #{number_to_human_size(post.attachment.size)}"
= f.input :attachment, as: :file, label: "File"
= f.input :attachment_cache, as: :hidden
= f.input :remote_attachment_url, label: "Enter URL to an image"
= f.input :content, input_html: { rows: '15' }

= f.button :submit, class: 'btn-primary'

【讨论】:

    猜你喜欢
    • 2012-12-03
    • 2014-06-26
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    相关资源
    最近更新 更多