Rails 4 - 在数据库

时间:2015-06-11 08:33:10

标签: jquery ruby-on-rails

我正在尝试在Rails 4中创建一个应用程序。

我有一个名为finalize的模型,它有两个属性。一个是名为:draft的布尔值,另一个是名为:finalised_at的日期时间。 Finalize属于我的项目模型。项目已经完成了。

这个想法是用户创建新项目,但将它们存储为草稿直到准备发布。在我的项目展示页面中,我的展示页面上有一个链接,以便在创建项目时if:draft为true,您可以单击链接将其切换为false。

当:草稿变为虚假时,我想写:发布于[插入日期:草稿变为假]。

我的目标是在我的项目页面上建立一个链接,该链接仅对创建项目的用户可见,并且只有:draft为true。链接说"敲定草稿"并且是一个将草稿属性切换为false的链接。只要草稿是假的(当点击此链接时,或者如果创建了新项目并且从未将其保存为草稿,因为草稿从创建点开始为假),则显示项目不再是草稿的日期对项目展示页面上的所有用户。

我想做的是编写一种方法,知道如何捕获用户点击链接以生成项目的日期:draft = false。目前,我使用Time.now函数完成所有工作,而不是草稿变为假的时间。

我的第一次尝试是:

在我的终结控制器中,我有:

  def toggle_draft
    @finalise = Finalise.find(params[:id])
    @finalise.draft = false
    @finalise.finalised = Time.now
    @finalise.save
    redirect_to project_path(Project.find(params[:projectid]))
  end

在我的最终视图中,我有:

<% if @project.finalise.draft == true %>

    <%= link_to 'Finalise draft', finalise_toggle_draft_path(projectid: @project.id, id: @project.finalise.id, finalise_id: @project.finalise.id), method: :patch %>
<% end %>

<% if @project.scope.finalise.draft == false %>
    <div class="datasubtextq">Published on <%= @project.scope.finalise.finalised.try(:strftime, '%d %B %Y') %></div>
<% end %>

我接着在下面收到了一条建议,尽管该用户现在建议它可能没有用于此目的:

该建议涉及在我的finalises.rb中包含一个方法,如下所示,并将我的观点改为:

<% if @project.scope.finalise.draft == false %>
    <div class="datasubtextq">Published on <%= @project.scope.finalise.finalised_at.try(:strftime, '%d %B %Y') %></div>
<% end %>

在finalise.rb

def set_finalised_if_published
    if self.draft_changed? && !self.draft
      self.finalised_at = Time.now
      self.save
    end
  end

使用下面的建议,我将我的finalises_controller修改为:

 def toggle_draft
    @finalise = Finalise.find(params[:id])
    @finalise.draft = false
    # @finalise.finalised = Time.now
    @finalise.save
    redirect_to project_path(@finalise.scope.project.id])
  end

在我的routes.rb中,我有:

resources :finalises do
   patch '/toggle-draft', to: 'finalises#toggle_draft', as: 'toggle_draft'
  end

当我尝试这个时,我收到的错误是:

No route matches {:action=>"toggle_draft", :controller=>"finalises", :id=>62} missing required keys: [:finalise_id]

我现在害怕尝试各种建议比我在开始这个帖子之前所做的更糟糕。我现在得到一个错误,说明未定义的方法最终确定&#39;。我没有一个名为finalize的方法。我有一个名为finalise.rb的模型

有没有人知道如何写一些东西来捕捉日期:草稿在db中等于false?

谢谢

2 个答案:

答案 0 :(得分:3)

我认为您应该使用ActiveRecord回调,例如after_save。在此回调中,您可以使用模块ActiveModel :: Dirty提供的方法来观察模型中的更改。

示例,在您的Finalize模型中:

after_save :set_finalized_if_published

def set_finalized_if_published
  if self.draft_changed? && !self.draft
    self.finalized = Time.now
    self.save
  end
end

答案 1 :(得分:1)

密钥将在提交到数据库之后和更新之前拦截事件。解决此问题的一种方法是使用您编写的当前toggle_draft方法并向模型添加方法:

敲定控制器

def toggle_draft
  @finalise = Finalise.find(params[:finalise_id])
  @finalise.draft = false

  if @finalise.save
    redirect_to project_path(@finalise.project), notice: 'Successfully Updated'
  else
    redirect_to project_path(@finalise.project), alert: 'Not Updated'
  end
end

然后在 finalise.rb模型文件中添加以下内容:

after_validation :set_publish_time
def set_publish_time
  self.finalised = Time.now  unless self.draft
end

如果您有任何问题,请告诉我

ALSO

对于您的路由问题,请尝试保留您的路线:

resources :finalises do
    patch 'toggle-draft', to: 'finalises#toggle_draft', as: :toggle_draft
end

所以路线将是:

finalise_toggle_draft_path(@project.finalise)

并确保在创建项目记录时创建finalize记录,这样当您将变量加载到路径中时,它不会返回id的nil。

Product.rb模型

after_create :create_a_finalise
def create_a_finalise
    self.finalise.create draft: true
end

其他选项:

如果使用此选项,请不要使用上述after_create代码

def create_a_finalise_dynamic(boolean)
    self.finalise.create draft: boolean
end

将它放在产品#create动作中,但它适合。

EX,您可以在表单中添加一个额外的参数复选框,名为&#39; final_draft&#39;这不是在你的数据库中,也不是通过强大的参数来获知他们是否需要草案:

def create
  @product = Product.new product_params

  if @product.save
    # if the checkbox is checked make the draft value false
    boolean = params[:product][:final_draft] == 1 ? false : true
    @product.create_a_finalise_dynamic boolean
    redirect_to projects_path, notice: 'Created!'
  else
    render :new
  end
end