【问题标题】:Add a password validation in a form_for before submitting review (Ruby on Rails)在提交审核之前在 form_for 中添加密码验证(Ruby on Rails)
【发布时间】:2018-06-19 17:36:17
【问题描述】:

我是 Ror 的新手。

在为特定产品创建评论之前,我想在我的 form_for 中添加一个密码字段。此 review.password 应与 product.reviewcode 匹配:

  • 如果匹配,则为该产品创建评论。
  • 如果没有,您会收到通知:“密码错误...再试一次..”

我已经为此工作了好几天,但无法在我的应用程序上执行此功能... :-( 任何想法...请 :-)

这是我的代码:


views/reviews.form.html.erb:
<% if @reviews.present? %>
Il y a deja un commentaire.
<% else %>
<%= form_for([@product, @product.reviews.new]) do |f| %>
<div id="user_stars"></div>
<%= f.text_area :comment, rows: 3, class: "form-control" %>
<%= f.hidden_field :product_id, value: @product.id %><br>

<%=f.label "Mot de passe communiqué par le vendeur:" %>
<%=f.password_field :password %>


<div class="actions">
  <%= f.submit "Evaluez", class: "btn btn-primary" %>
</div>
<% end %>
<% end %>

reviews_controller.rb:
class ReviewsController < ApplicationController
 before_action :authenticate_user!

 def create
  @review.password = nil
  unless @review.password == @product.reviewcode
   @review = current_user.reviews.new(review_params)
   @review.save
   redirect_to @review.product
 else
  render :create, notice: "Le code n'est pas bon"
  end
end

private

def review_params
  params.require(:review).permit(:comment, :star, :product_id, :user_id, :password)
end

def set_product
  @product = Product.find(params[:product_id, :reviewcode])
end

end

product.rb:
class Product < ApplicationRecord
  belongs_to :user
  has_many :photos
  has_many :reservations
  has_many :reviews

  validates :category, presence: true
  validates :state, presence: true
  validates :color, presence: true
  validates :brand, presence: true
  validates :size, presence: true
  validates :name, presence: true, length: { maximum: 25 }
  validates :description, presence: true, length: { maximum: 70 }
  validates :address, presence: true
  validates :price, numericality: { only_integer: true, greater_than: 1 }
  validates :status, inclusion: { in: [true, false] }
  validates :reviewcode, presence: true

  def reviewcode
    reviewcode = "1234"
  end
end

review.rb:
class Review < ApplicationRecord
  belongs_to :product
  belongs_to :user

validates :comment, presence: true
validates :star, presence: true
validates :product_id, presence: true
validates :password, presence: true
end

【问题讨论】:

  • 感谢您分享您的代码。你知道你哪里有问题吗?我注意到您的控制器中有@review.password = nil。看起来审查密码将永远为零。这是故意的吗?
  • 当您在 create 操作中定义 @product 时?

标签: ruby-on-rails ruby model-view-controller passwords form-for


【解决方案1】:

我认为问题在于您使用的是除非。 除非基本上是在说“如果不是”,所以在您的代码中
unless @review.password == @product.reviewcode 表示 if @review.password != @product.reviewcode。此外,正如Derek Hopper 评论的那样,您始终将密码设置为nil,我不知道这是不是故意的。

reviews_controller.rb

class ReviewsController < ApplicationController
  before_action :authenticate_user!

  def create
    # @review.password = nil I think this should be deleted
    if check_password
      @review = current_user.reviews.new(review_params)
      @review.save
      redirect_to @review.product
    else
      render :create, notice: "Le code n'est pas bon"
    end
  end

private

  def review_params
    params.require(:review).permit(:comment, :star, :product_id, :user_id, :password)
  end

  def set_product
    @product = Product.find(params[:product_id, :reviewcode])
  end

  def check_password
    return @review.password == @product.reviewcode
  end

end

编辑

至于您的评论,我猜您的reviews_controller.rb 中有另一种方法,您可以在其中“调用”视图。在这种方法中,你应该有这样的东西:

def new
  @review = @product.reviews.new
  #Use this @review insted of @product.reviews.new in the html file
end

【讨论】:

  • 感谢您的快速回复,但我仍然遇到以下问题:ReviewsController#create undefined method `password' for nil:NilClass 中的 NoMethodError 提取的源代码(第 27 行附近):def check_password return @review .password == @product.reviewcode end end
  • Thks Chester,但仍然无法正常工作 :-( 到目前为止还没有成功......好吧......没有条件:“如果 check_password”在我的 Review Controller /create 操作中:评论是为产品正确创建的。但是如果我添加这个条件,它会返回我:NoMethodError in ReviewsController#create undefined method `password' for nil:NilClass...(我没有在我的评论控制器中使用新方法:我通过调用 ) 在我的产品展示中直接显示表单
  • 那么如果不是调用 check_password 而是直接在 create 操作上运行那段代码,它会起作用吗?
  • 它不工作......即使直接在创建方法中集成条件而不是 def check_password
  • 在这段代码之后你有一个新的审查实例。正如我之前在你的产品展示方法中感到难过的那样,你应该做一些像@review = @product.reviews.new 这样的事情并将其作为参数传递给表单
【解决方案2】:

感谢:@ChesterLaborde,@Derek Hopper,@inye 所以这是最后一个问题。无需在 Product 模型中创建方法。并且新操作直接包含在 Product Show 中,然后在 Review Controller 中只需要以这种方式进行(如果我需要一个等于我的 product.price*10 的代码):

class ReviewsController < ApplicationController
  before_action :authenticate_user!

  def create
    @review = current_user.reviews.new(review_params)
    if check_password
      @review.save
      redirect_to @review.product
    else
      redirect_to @review.product, notice: "Le code est incorrect"
    end
  end

  private

  def review_params
    params.require(:review).permit(:comment, :star, :product_id, :user_id, :password)
  end

  def check_password
  @product = Product.find(params[:product_id])
    return @review.password == @product.price*10
  end

end

【讨论】:

    猜你喜欢
    • 2014-09-05
    • 2011-07-04
    • 2014-10-19
    • 1970-01-01
    • 2019-02-08
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多