如何从一个提交更新两个_form?

时间:2016-03-14 18:03:55

标签: javascript ruby-on-rails ruby forms submit

如果他选择,current_user如何更新他的电子邮件而无需单独的提交按钮?

当前代码

<%= form_for(@challenge)  do |challenge| %>
  <%= challenge.action %>
  <%= challenge.send_email %>
<% end %>

<%= form_for(current_user)  do |user| %>
  <%= user.email %>
  <%= user.submit %>
<% end %>

<%= form_for(@challenge)  do |challenge| %>
  <%= challenge.submit %>
<% end %>

整体想法

<%= form_for(@challenge)  do |challenge| %>
  <%= challenge.action %>
  <%= challenge.send_email %>

  <%= form_for(current_user)  do |user| %> # Or somehow remove form_for(current_user) altogether while still being able to update current_user.email within the form_for(@challenge)
    <%= user.email %>
  <% end %>

  <%= challenge.submit %>
<% end %>

_form的图片

enter image description here

提供控制器代码,看看我们是否可以通过fields_for

来完成这项工作

challenges_controller

class ChallengesController < ApplicationController
  before_action :set_challenge, only: [:show, :edit, :update, :destroy, :challenging, :mark_accomplished, :mark_completed, :create_freebie, :like]
  respond_to :html, :json

  def show
    @challenge_to_deadline = current_user.challenges.group_by {|i| i.deadline} if current_user
    @notable = @challenge
    @notes = @notable.notes
    @note = Note.new
    @commentable = @challenge
    @comments = @commentable.comments
    @comment = Comment.new
    @correct_user = current_user.challenges.find_by(id: params[:id])
  end

  def new
    @challenge = Challenge.new
    respond_modal_with @challenge, location: root_path
  end

  def edit
  end

  def create
    @challenge = Challenge.new(challenge_params)
    if params[:step] == '2'
      if current_user == nil
        # If there is no user, store the lifetime values to the session.
        session[:challenge_action] = challenge_params[:action]
        session[:challenge_committed] = challenge_params[:committed]
        session[:challenge_deadline] = [params["challenge"]["deadline(3i)"], params["challenge"]["deadline(2i)"], params["challenge"]["deadline(1i)"]].join('/')
        session[:challenge_date_started] = [params["challenge"]["date_started(3i)"], params["challenge"]["date_started(2i)"], params["challenge"]["date_started(1i)"]].join('/')
        session[:challenge_order] = challenge_params[:order]
        session[:challenge_days_challenged] = challenge_params[:days_challenged]
        session[:challenge_why] = challenge_params[:why]
        session[:challenge_conceal] = challenge_params[:conceal]
        redirect_to signup_path
      else
        @challenge = current_user.challenges.build(challenge_params)
        if @challenge.conceal == true
          @challenge.save
          redirect_to root_path
          if @challenge.date_started.present?
            flash[:info] = 'habit Challenge secretly saved! Click "Strike 1" upon incompleting a day.'
          else
            flash[:info] = 'goal Challenge secretly saved! Click checkmark upon completing it.'
          end
        elsif
          @challenge.save
          track_activity @challenge
          redirect_to root_path
          if @challenge.date_started.present?
            flash[:info] = 'habit Challenge saved! Click "Strike 1" upon incompleting a day.'
          else
            flash[:info] = 'goal Challenge saved! Click checkmark upon completing it.'
          end
        else
          respond_modal_with @challenge
        end
      end
    end
  end

  def update
    @challenge.update(challenge_params)
    flash[:info] = 'Challenge updated'
    respond_modal_with @challenge, location: root_path
  end

private

  def set_challenge
    @challenge = Challenge.find(params[:id])
  end

  def challenge_params
    params.require(:challenge).permit(
      :action,
      :why, 
      :like, 
      :deadline, 
      :accomplished, 
      :tag_list, 
      :conceal,
      :archive,
      :trigger,
      :missed_days,
      :target, 
      :reward,
      :order,
      :date_started,
      :date_ended,
      :days_challenged,
      :completed_at,
      :freebie,
      :freebie_date, 
      :send_email => [],
      :committed => [])
  end
end

users_controller

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
  before_action :correct_user,   only: [:edit, :update]

  def show
    @user = User.find(params[:id])
    @past_challenges = @user.challenges.publish.order("deadline ASC").select{ |challenge| challenge.deadline < Date.current if challenge.deadline.present? }
    @past_challenges_by_years = @past_challenges.group_by { |t| t.deadline.beginning_of_year }
    @present_oneshot_challenges = @user.challenges.unaccomplished.publish.order("deadline ASC").select{ |challenge| challenge.deadline == Date.current if challenge.deadline.present? }
    @present_habit_challenges = @user.challenges.unaccomplished.publish.order("date_started DESC").select{ |challenge| challenge.date_started <= Date.tomorrow if challenge.date_started.present? }
    @future_challenges = @user.challenges.unaccomplished.publish.order("deadline ASC").select{ |challenge| challenge.deadline > Date.current if challenge.deadline.present? }
    @future_challenges_by_years = @future_challenges.group_by { |t| t.deadline.beginning_of_year }
    @inspirations = @user.inspirations.publish
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      action = session.delete(:challenge_action)
      deadline = session.delete(:challenge_deadline)
      committed = session.delete(:challenge_committed)
      date_started = session.delete(:challenge_date_started)
      order = session.delete(:challenge_order)
      days_challenged = session.delete(:challenge_days_challenged)
      why = session.delete(:challenge_why)
      conceal = session.delete(:challenge_conceal)
      # Create
      if deadline.present?
        @user.challenges.create(action: action, deadline: deadline, why: why, conceal: conceal, date_started: date_started, committed: committed, days_challenged: days_challenged)
      end
      @user.send_welcome_email
      log_in @user
      redirect_to tutorial_url
      flash[:info] = 'Let the games begin! Add another challenge with + Challenge'
    else
      render 'new'
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      redirect_to root_url
      flash[:success] = "Settings updated"
    else
      render 'edit'
    end
  end

  private

  def user_params
    if params[:conceal] = true
      params.require(:user).permit(:time_zone, :name, :email, :tag_list, :password, :conceal, inspirations_attributes: [:name, :tag_list, :conceal], activities_attributes: [:conceal, :action, :trackable_id, :trackable_type])
    else
      params[:user][:conceal] = false
      params.require(:user).permit(:time_zone, :name, :image, :tag_list, :email, :password, inspirations_attributes: [:name, :tag_list], activities_attributes: [:action, :trackable_id, :trackable_type])
    end
  end

  # Confirms a logged-in user.
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please sign in first"
        redirect_to root_url
      end
    end

    # Confirms the correct user.
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end
end

1 个答案:

答案 0 :(得分:2)

在另一个$conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT * from textDocs"; $result = $conn->query($sql); $res = array(); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { array_push($res,array('t'=>$row['t'],'co'=>$row['cover'], 'text'=>$row['txt'])); } } else { return false; } $conn->close(); 中嵌入form无效form。页面中可以有多个表单,但它们不能相互嵌入。

如果您想要使用相同形式的不同模型的字段,根据这些模型之间的关联,您可以使用html中的fields_for来渲染表单字段楷模。然后,当提交表单时,再次根据模型之间的关联,您可以保留数据。

您还可以使用form_for并提交/更新表单的部分内容。例如:当javascript的内容发生变化时,您可以触发text_field请求并保留数据。

有关详细信息,请参阅FormHelper#fields_for

<强>更新

根据您在评论中的回答,您有以下模型:

AJAX

你有两种方法。

方法1:通过class User < ActiveRecord::Base has_many :challenges end class Challenge < ActiveRecord::Base belongs_to :user end 动作过滤器。从controller中的email拦截用户的params并进行更新。类似的东西:

controller

并按如下方式更新您的表单代码:

class ChallengesController < ApplicationController
  before_action :update_user_email, if: proc {|c| c.current_user.present? && c.params[:email].present? }
  private
  def update_user_email
    email = params[:email]
    current_user.update_attribute(:email, email)
  end
end

方法2:通过<%= form_for(@challenge) do |challenge| %> # include fields for challenge <%= text_field_tag :email, current_user.email %> <%= challenge.submit %> <% end %> 回调。在模型中使用modelattr_accessor的组合。

callbacks

并按如下方式更新您的表单代码:

class Challenge < ActiveRecord::Base
  belongs_to :user

  attr_accessor :user_email
  before_save :update_user_email, if: :user_email_present?

  protected
  def user_email
    self.user.email if self.user.present?
  end 

  def user_email_present?
    self.user_email.present?
  end

  def update_user_email
    # based on your logic in controller, looks like the 
    # `current_user` and the `user` of the `challenge` 
    # are one and the same. So you could directly update
    # `email` on the `user` object.
    self.user.update_attribute(:email, self.user_email)
  end
end