2017-04-26 81 views
0

我有一个后端显示帖子列表的博客。每个帖子都有一个publish_on值,这是一个日期时间 - 如果当前时间晚于publish_on,则帖子处于活动状态(帖子有一个名为active的布尔虚拟字段)。修改Phoenix中的结构列表

当我查询回购的帖子列表时,如果当前时间在publish_on之后,我想查看列表,并将帖子的active设置为true。

什么是最“Elixirian”的方式来做到这一点? (此外,什么是药剂界的 “Python化” 的版本?)

型号/ post.ex

defmodule MyApp.Post do 
    use MyApp.Web, :model 

    schema "posts" do 
    field :title, :string 
    field :content, :text 
    field :publish_on, Ecto.DateTime 
    field :active, :boolean, virtual: true, default: false 

    timestamps() 
    end 

控制器/ post_controller.ex

MyApp.PostController 
    def index(conn, _params) do 
    query = from p in Post, 
    posts = Repo.all(query) 

    ###I assume some kind of mapping goes here 

    render(conn, "index.html", posts: posts) 
    end 

模板/后/ index.html的.eex

<table class="table"> 
<%= for post <- @posts do %> 
    <%= if post.active do %> 
     <tr class="published"> 
    <% else %> 
     <tr class="unpublished"> 
    <% end %> 

回答

2

我会去通过使用for的职位,比较DateTime.utc_nowpost.publish_on使用DateTime.compare,如果它是:gt,设置activetrue

posts = Repo.all(query) 

now = DateTime.utc_now 

posts = for post <- posts do 
    case DateTime.compare(now, post.publish_on) do 
    :gt -> %{post | active: true} 
    _ -> post 
    end 
end 
+0

这正是我所期待的。我似乎得到了'DateTime.compare()':'DateTime.compare/2'中没有函数子句匹配的错误。它不会抛出这个,如果我运行'DateTime.compare(现在,现在)',所以我猜它必须与post.publish_on的类型。 –

+1

@MarkKaravan看起来像是'Ecto.DateTime'。在升级到使用新DateTime的版本之前,可以使用DateTime.utc_now - > Ecto.DateTime.utc和DateTime.compare - > Ecto.DateTime.compare。 – Dogbert

2

您可以在查询初始化虚拟领域:

query = from p in Post, select: %{p | active: (s.publish_on < ^DateTime.utc_now())} 
posts = Repo.all(query) 
+0

非常有用。什么是%{this |的名称那}结构? –

+1

@MarkKaravan http://elixir-lang.org/getting-started/structs.html#accessing-and-updating-structs只是将其称为'更新语法'。 –