【问题标题】:How to send arbitrary parameters to controller using simple_form如何使用 simple_form 向控制器发送任意参数
【发布时间】:2017-01-30 17:06:47
【问题描述】:

我正在构建一个时事通讯管理表单,我想使用 simple_form。 email 参数应该通过POST 方法发送到email_subscriber#manage 控制器/动作。

routes.rb

get 'email/login' => 'email_subscribers#login', as: 'email_login'
get 'email/manage' => 'email_subscribers#manage', as: 'email_manage'

email_subscribers_controller.rb

def login

end

def manage
    @subscriber = EmailSubscriber.find_by_email(safe_params(:email))

    unless @subscriber
        # redirect_to email_login_path, notice: 'That email does not exist.'
    end
end

电子邮件/登录表单

<%= render :layout => 'application/container' do %>
    <%= simple_form_for(@subscriber, path: :email_manage_path, method: :get) do |f| %>
            <%= f.error_notification %>

            <div class="form-inputs">
                <%= f.input :email, as: :email %>
            </div>

            <div class="form-actions">
                <%= f.button :submit, value: 'Manage Subscription' %>
            </div>
    <% end %>

登录路径是表单所在的位置。它允许用户输入他们的电子邮件以取消订阅时事通讯。

表单应重定向到manage 操作,传递没有对应模型的email 参数。

当前表单不起作用。由于某种原因,它重定向到EmailSubscribers 索引页面。 将email_manage 路由更改为POST 会导致missing route POST email/login,因为表单发布到email_manage_path,而不是email_login_path

谢谢

编辑:

rake 路由输出(在同一选项卡中打开)

http://pastebin.com/eFGdvxid

【问题讨论】:

  • 你能发布你的路线吗? rake routes
  • 添加了一个包含完整 rake routes 输出的 pastebin

标签: ruby-on-rails ruby simple-form


【解决方案1】:

您实际上可以将其建模为传统的 RESTful 资源:

resources :subscriptions
namespace :subscriptions do
  resources :logins
  get '/login', to: 'logins/create'
end

优点是您可以获得更简单的设置,遵循规范的 crud 动词,并且您还可以使用正确的 HTTP 动词。

这里唯一不合常规的部分是我们通过 GET 向create 添加了一条额外的路由:

# app/controllers/subscriptions/logins_controller.rb
class Subscriptions::LoginsController < ApplicationController
  rescue_from ActionController::ParameterMissing, with: :subscription_not_found

  # GET /subscriptions/logins/new
  def new
    @subscription = Subscription.new
  end

  # POST /subscriptions/logins
  # GET /subscriptions/login
  def create
    @subscription = Subscription.find_by_email(email_param)
    if @subscription
      redirect_to edit_subscription_path(@subscription)
    else
      subscription_not_found
    end
  end

  private

  def subscription_not_found
    render :new, error: 'Email could not be found.'
  end

  def email_param
    if request.post?
      params.require(:subscription).fetch(:email)
    else
      params.fetch(:email)
    end
  end
end

由于我们实际上是绑定到资源的,因此您可以以非常直接的方式设置表单。我们还添加了一个 GET 路由,让用户可以直接从链接登录。

表格非常简单。

<%= simple_form_for(@subscription, path: subscriptions_sessions_path) do %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :email, as: :email %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, value: 'Manage Subscription' %>
  </div>
<% end %>

然后您可以创建一个漂亮的 mill CRUD 控制器运行,让用户编辑或取消订阅:

# app/controllers/subscriptions_controller.rb
class SubscriptionsController < ApplicationController

  before_action :set_subscription, only: [:edit, :update, :destroy]
  rescue_from ActiveRecord::RecordNotFound, with: :invalid_email

  def new
    @subscription = Subscription.new
  end

  def create
    @subscription = Subscription.new(subscription_params)
    if @subscription.save(subscription_params)
      redirect_to root_path, success: 'Your subscription settings have been creates'
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @subscription.update(subscription_params)
      redirect_to root_path, success: 'Your subscription settings have been updated'
    else
      render :edit
    end
  end

  def destroy
    @subscription.destroy
    redirect_to root_path
  end

  private 

  def set_subscription
    @subscription = Subscription.find(params[:id])
  end

  def subscription_params
    params.require(:subscription).permit(:foo, :bar, :baz)
  end
end

【讨论】:

  • 我需要一些时间来让这个问题深入人心。从技术上讲,我不回答这个问题,因为我仍然想知道如何在没有模型的情况下使用 simple_form,但我确实喜欢你的方法。非常聪明!现在将您的答案集成到我的应用中。
  • 您可以通过创建包含ActiveModel::Model 的“虚拟”模型来使用它而无需表支持模型,或者您只需使用普通的旧rails 标签助手来创建输入元素。 SF 不能在没有模型的情况下工作。
  • 另外,创建您在电子邮件中发送的令牌而不是使用用户电子邮件作为参数也是一个好主意。 api.rubyonrails.org/classes/ActiveRecord/SecureToken/…
  • 为什么/login 路由会转到sessions#create?不应该去logins#create吗?
猜你喜欢
  • 2010-12-25
  • 2011-07-03
  • 2020-01-24
  • 2014-12-23
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 2015-11-21
  • 2010-12-05
相关资源
最近更新 更多