为什么我的控制器没有在用户控制器的创建操作中设置属性? - Rails 3

时间:2011-08-24 22:41:47

标签: ruby-on-rails ruby-on-rails-3

这是创建动作:

  def create
    @user = User.new(params[:user])
    @user.coupon_code = params[:xcode]

    respond_to do |format|
      if @user.save
        UserMailer.welcome_email(@user).deliver

        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

基本上我想要做的是在保存用户之前,我想将新创建的用户的属性coupon_code设置为通过params[:xcode]发送的字符串。

我知道值在我的参数中,如日志输出中所示:

Started POST "/users" for 127.0.0.1 at 2011-08-24 17:33:07 -0500
  Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Jp2GHxnuVOVnI/sfr1CB4EQ9URCTJynv/2Ek4AiU8Lg=", "user"=>{"username"=>"test.user", "first_name"=>"Testing", "last_name"=>"User", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "email"=>"testuser@abc.com", "plan_id"=>"1"}, "xcode"=>"testusercoupon", "commit"=>"Register"}
nil
  SQL (0.2ms)  SELECT 1 FROM "users" WHERE (LOWER("users"."email") = LOWER('testuser@abc.com')) LIMIT 1
  Plan Load (0.3ms)  SELECT "plans".* FROM "plans" WHERE "plans"."id" = 1 ORDER BY id LIMIT 1
  SQL (0.2ms)  SELECT 1 FROM "users" WHERE (LOWER("users"."username") = LOWER('test.user')) LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "users" WHERE (LOWER("users"."email") = LOWER('testuser@abc.com')) LIMIT 1
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'b2GnABnQ1on-K_2Dwf3M' LIMIT 1
  Role Load (0.2ms)  SELECT "roles".* FROM "roles" WHERE "roles"."name" = 'designer' LIMIT 1
  AREL (0.4ms)  INSERT INTO "users" ("email", "encrypted_password", "password_salt", "reset_password_token", "remember_token", "remember_created_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "username", "first_name", "last_name", "created_at", "updated_at", "invitation_token", "invitation_sent_at", "plan_id", "current_state", "confirmation_token", "confirmed_at", "confirmation_sent_at", "space_used", "failed_attempts", "unlock_token", "locked_at", "trial_end_date", "active_subscription", "customer_id", "coupon_code") VALUES ('testuser@abc.com', '$2a$10$DerQxksUpQhoD.QheuxYneNGo7Nd2lHIzbtJrpCnd3lRTY/NFH9RK', '$2a$10$DerQxksUpQhoD.QheuxYne', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'test.user', 'Testing', 'User', '2011-08-24 22:33:07.660722', '2011-08-24 22:33:07.660722', NULL, NULL, 1, NULL, 'b2GnABnQ1on-K_2Dwf3M', NULL, '2011-08-24 22:33:07.542240', 0, 0, NULL, NULL, '2011-09-07', NULL, NULL, NULL)
Rendered devise/mailer/confirmation_instructions.html.erb (1.5ms)

但是,正如您在AREL语句中看到的那样NULL被插入到数据库中。

如何将params值输入db?

P.S。我尝试将其作为模型中的回调(例如before_save),但问题是从表单字段中获取值。据我所知,我无法将表单字段(即params[:xcode])中的数据直接传递给我的模型。我必须在控制器中执行...所以这就是为什么我这样做了。救命啊!

编辑1:

用户模型,特别是before_filters

class User < ActiveRecord::Base
    acts_as_voter
  devise :database_authenticatable, :confirmable, :registerable, :timeoutable,
         :recoverable, :rememberable, :trackable, :validatable, :invitable, :lockable

  attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :first_name, :last_name, :plan_id
  has_friendly_id :username, :use_slug => true, :strip_non_ascii => true
  validates_presence_of :username, :email, :plan
  validates_uniqueness_of :username, :email, :case_sensitive => false

  before_create :assign_default_role
  after_validation :set_trial_end

def set_trial_end
  plan = self.plan
  end_of_trial = Date.today + self.plan.trial_duration.days
  self.trial_end_date = end_of_trial.to_date
end

编辑2:这是发回params[:xcode]

的表单元素
<div class="settings_form">
    <% @user.plan_id = params[:plan_id] %>

    <%= devise_error_messages! %><br />

    <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>

        <% if !params[:promo] %>
            <%= f.collection_select :plan_id, @plan, :id, :display_name, :prompt => "Choose yourself up a real nice plan" %><br />
        <% end %>
        <%= f.text_field :username, :placeholder => "Desired Username" %><br />
        <%= f.text_field :first_name, :placeholder => "First Name" %><br />
        <%= f.text_field :last_name, :placeholder => "Last Name" %><br />
        <%= f.password_field :password, :placeholder => "Password" %><br />
        <%= f.password_field :password_confirmation, :placeholder => "Password" %><br />
        <%= f.text_field :email, :placeholder => "Email Address" %><br />
        <% if params[:promo] %>
            <%= text_field_tag "xcode", :placeholder => "Coupon Code" %><br /> 
        <%= hidden_field_tag 'user[plan_id]', "1" %>
        <% end %>
        <div class="settings_button">
            <%= f.submit "Sign in", :id => "register", :value => "Register", :class => "pill button" %>
        </div>

        <% end %>

</div>

1 个答案:

答案 0 :(得分:2)

您是否尝试过更改ERB视图代码以便

  <%= text_field_tag "xcode", :placeholder => "Coupon Code" %><br /> 

变为

  <%= text_field_tag "user[coupon_code]", :placeholder => "Coupon Code" %><br /> 

然后删除控制器操作以分配此值? 事实上,您甚至可以用

替换它
<%= f.text_field :coupon_code, :placeholder => "Coupon Code" %>

只要它在ERB if语句中,它只会在适当的条件下显示,并且你的控制器不必重命名参数。