Leveraging Cloving CLI’s Chat Feature to Build a Rails, React, and AI-Powered Micro App

Richard Baldwin's Technical Blog

Leveraging Cloving CLI’s Chat Feature to Build a Rails, React, and AI-Powered Micro App

Modern development tools like Cloving CLI are revolutionizing how developers interact with AI in their workflows. Cloving CLI’s chat functionality offers a streamlined and interactive way to incorporate AI into development tasks, including creating micro apps. This blog post demonstrates how to use Cloving CLI’s chat feature to build a Rails-based micro app that integrates a WordPress API, React frontend, and AI for content enhancement.

Project Overview

Our micro app enables users to:

  1. Search for WordPress posts via a Rails API.
  2. View and select posts in a React app.
  3. Modify posts using AI-enhanced suggestions via Rails.
  4. Save the updated posts back to WordPress.

This workflow will focus on Cloving CLI’s interactive chat feature to scaffold components, refine APIs, and facilitate AI interactions.


Section 1: Initializing the Project with Cloving CLI

Cloving CLI simplifies project scaffolding with context-aware AI commands. To start, set up the Rails backend and configure it to communicate with WordPress. Use the cloving generate code command to scaffold the necessary components.

cloving init --model openai

After initializing the project, you can generate code directly using Cloving CLI:

cloving generate code --prompt "Generate a Rails controller for connecting to the WordPress REST API and handling search requests."

This command instructs Cloving to generate the code for a Rails controller that connects to the WordPress REST API and handles search requests. Cloving uses AI to create code snippets based on the provided prompt, streamlining the development process.

Generated Rails Controller Example:

class Api::V1::PostsController < ApplicationController
  require 'httparty'

  # GET /api/v1/posts/search?query=your_search_term
  def search
    query = params[:query]
    wordpress_api_url = "https://your-wordpress-site.com/wp-json/wp/v2/posts?search=#{query}"

    response = HTTParty.get(wordpress_api_url)

    if response.success?
      render json: response.parsed_response, status: :ok
    else
      render json: { error: 'Failed to fetch posts from WordPress' }, status: :bad_request
    end
  end
end

In this controller:

  • Namespace: The controller is namespaced under Api::V1 to indicate versioning for your API.
  • HTTParty: Utilizes the HTTParty gem to make HTTP requests to the WordPress REST API.
  • Search Action: The search method accepts a query parameter from the frontend, constructs a request to the WordPress API, and returns the JSON response.
  • Error Handling: Includes basic error handling to manage unsuccessful API requests.

With this controller in place, your Rails API can handle search requests from the React frontend, query the WordPress API, and send back the search results in a structured format.


Section 2: Handling API Responses and Structuring Data

With our Rails controller now set up to fetch posts from the WordPress API, the next step is ensuring the data returned from WordPress is properly structured and ready to send to the React frontend. This involves processing the API response to include only the necessary information and organizing it into a consistent format.


Formatting API Responses

WordPress posts retrieved through the API often contain a wealth of metadata, much of which may not be needed in the React frontend. To streamline this data, we can use a serializer in Rails to extract only the relevant fields. For example, we might include fields like the post title, excerpt, content, and permalink.

To handle this, create a serializer using the Active Model Serializers gem:

bundle add active_model_serializers

Generate the Serializer:

rails generate serializer Post

Modify the Serializer:

class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :excerpt, :content, :permalink

  def title
    object['title']['rendered']
  end

  def excerpt
    object['excerpt']['rendered']
  end

  def content
    object['content']['rendered']
  end

  def permalink
    object['link']
  end
end

Here, the serializer maps the relevant fields from the WordPress API response to attributes that the React frontend can use.


Updating the Controller to Use the Serializer

Next, update the search action in the PostsController to use the PostSerializer for formatting the response before sending it back to the frontend.

Updated Controller Action:

def search
  query = params[:query]
  wordpress_api_url = "https://your-wordpress-site.com/wp-json/wp/v2/posts?search=#{query}"

  response = HTTParty.get(wordpress_api_url)

  if response.success?
    posts = JSON.parse(response.body)
    render json: posts.map { |post| PostSerializer.new(post).as_json }, status: :ok
  else
    render json: { error: 'Failed to fetch posts from WordPress' }, status: :bad_request
  end
end

In this version:

  • JSON Parsing: The response body from WordPress is parsed into a Ruby hash.
  • Serializer Application: Each post in the response is passed through the PostSerializer to extract and format only the necessary fields.
  • Array Mapping: The serialized posts are returned as an array of structured JSON objects.

Preparing for the React Frontend

Now that the Rails API is returning clean, structured data, we’re ready to send this data to the React frontend in Section 3. The frontend will fetch these results, display them in a user-friendly format, and allow users to select a post for further actions.

This structured approach ensures that the Rails API remains a reliable intermediary between WordPress and React, offloading data processing and allowing the frontend to focus on user interaction.


Section 3: Setting Up the React Frontend with Cloving CLI

With our Rails API configured to retrieve and format WordPress posts, the next step is to set up a React frontend that can fetch and display these results. Here, we’ll use Cloving CLI to scaffold a React app, generate components for interacting with the Rails API, and handle user interactions.


Generating the React App and Components with Cloving CLI

Cloving CLI’s code generation feature can expedite the process of building out our frontend components. Start by using Cloving to initialize a new React app:

cloving generate code --prompt "Initialize a new React app for fetching and displaying data from a Rails API."

This command sets up the structure for a React app, including dependencies for communicating with APIs. Once the base app is ready, you can use Cloving’s code generation to create a component for displaying the search results from WordPress.


Creating the Post Search Component

To create the PostSearch component, prompt Cloving CLI to generate code that fetches data from an API and displays it in a list:

cloving generate code --prompt "Create a React component to fetch and display posts from a Rails API."

This command provides a scaffolded component that fetches posts from our Rails API and displays them in a list. You can then refine this component with Cloving’s interactive chat feature:

cloving chat

Example Cloving Chat Interaction:

  • Prompt: “Generate a React component that fetches search results from an API, displays them in a list, and allows the user to select a post.”

Cloving CLI will generate code for a component like this:

// src/components/PostSearch.js
import React, { useState } from 'react'
import axios from 'axios'

const PostSearch = () => {
  const [query, setQuery] = useState('')
  const [posts, setPosts] = useState([])
  const [selectedPost, setSelectedPost] = useState(null)

  // Handle form submission to search for posts
  const handleSearch = async (e) => {
    e.preventDefault()
    try {
      const response = await axios.get(`http://localhost:3001/api/v1/posts/search`, {
        params: { query }
      })
      setPosts(response.data)
    } catch (error) {
      console.error('Error fetching posts:', error)
    }
  }

  // Handle post selection
  const handleSelectPost = (post) => {
    setSelectedPost(post)
  }

  return (
    <div>
      <form onSubmit={handleSearch}>
        <input
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search WordPress posts..."
        />
        <button type="submit">Search</button>
      </form>

      <div>
        {posts.length > 0 && (
          <ul>
            {posts.map((post) => (
              <li key={post.id} onClick={() => handleSelectPost(post)}>
                <h3>{post.title}</h3>
                <p dangerouslySetInnerHTML={{ __html: post.excerpt }}></p>
              </li>
            ))}
          </ul>
        )}
      </div>

      {selectedPost && (
        <div>
          <h2>Selected Post: {selectedPost.title}</h2>
          <p dangerouslySetInnerHTML={{ __html: selectedPost.content }}></p>
          {/* Add further actions here, like expanding the content with AI */}
        </div>
      )}
    </div>
  )
}

export default PostSearch

Component Breakdown

  • State Management: query, posts, and selectedPost states manage the search term, list of posts, and the currently selected post.
  • Search Function: The handleSearch function sends a search query to the Rails API, updating posts with the results.
  • Display and Select Posts: The component renders the posts in a list and allows the user to select a post for further actions.

Integrating the Component into the React App

Finally, import and render the PostSearch component in your main App.js file:

cloving generate code --prompt "Set up the main App component to render the PostSearch component in a new React project."

With Cloving’s help, you’ll get the basic setup for your App component, which will look something like this:

// src/App.js
import React from 'react'
import './App.css'
import PostSearch from './components/PostSearch'

function App() {
  return (
    <div className="App">
      <h1>WordPress Post Search</h1>
      <PostSearch />
    </div>
  )
}

export default App

Testing the Integration

Run both the Rails and React applications to test the flow from search to post selection. This setup provides a user-friendly interface to search for WordPress posts, which prepares us for the next step: integrating AI to enhance the content of a selected post.

In Section 4, we’ll connect the Rails backend to an AI API to allow users to expand on any selected WordPress post, creating a seamless content augmentation workflow.


Section 4: Enhancing Post Content with AI and Cloving CLI

With our Rails API successfully retrieving and formatting WordPress posts and the React frontend displaying them, we’re ready to add AI-driven content enhancement. In this section, we’ll use Cloving CLI to scaffold code that enables Rails to interact with an AI API (such as OpenAI’s GPT-4) to expand the selected WordPress post’s content based on user requests. This enhancement workflow will allow users to select a post, request expanded content, review the AI-generated additions, and submit the modified post back to WordPress.


Setting Up the AI Integration with Cloving CLI

To start, let’s use Cloving CLI to generate the initial service code in Rails for connecting to the AI API. This service will take in a selected post’s content, send it to the AI API, and return the expanded content.

Use Cloving CLI to scaffold the service:

cloving generate code --prompt "Create a Rails service to connect to the OpenAI API and generate expanded content for a selected post."

Cloving will generate a service template similar to this:

# app/services/ai_content_service.rb
require 'net/http'
require 'uri'
require 'json'

class AiContentService
  OPENAI_API_URL = "https://api.openai.com/v1/completions"

  def initialize(api_key)
    @api_key = api_key
  end

  def expand_content(post_content)
    prompt = "Expand the following blog post content with additional insights and details:\n\n#{post_content}"

    response = Net::HTTP.post(
      URI.parse(OPENAI_API_URL),
      { model: "text-davinci-003", prompt:, max_tokens: 500 }.to_json,
      "Content-Type" => "application/json",
      "Authorization" => "Bearer #{@api_key}"
    )

    JSON.parse(response.body)["choices"][0]["text"].strip
  rescue => e
    Rails.logger.error("Failed to generate expanded content: #{e.message}")
    nil
  end
end

Here’s what this service does:

  • API Key Setup: Initializes the service with the AI API key.
  • expand_content Method: Sends a prompt to the AI API to expand the post content and returns the AI-generated text.
  • Error Handling: Logs errors in case of issues with the API call.

Integrating the AI Service in the Controller

Now that we have the AiContentService, let’s use Cloving CLI to help us integrate this service into our Rails controller. This integration will involve creating an endpoint that triggers the AI expansion process when a user selects a post.

Generate the controller action with Cloving:

cloving generate code --prompt "Add a controller action to call the AiContentService and return the expanded content for a selected post."

Cloving will create or update the controller with the following action:

# app/controllers/api/v1/posts_controller.rb

def expand_content
  post_content = params[:content]
  ai_service = AiContentService.new(ENV['OPENAI_API_KEY'])
  expanded_content = ai_service.expand_content(post_content)

  if expanded_content
    render json: { expanded_content: }, status: :ok
  else
    render json: { error: 'Failed to generate expanded content' }, status: :unprocessable_entity
  end
end

In this action:

  • Parameters: The expand_content action accepts content from the frontend, which contains the selected post’s content.
  • AI Service Call: It initializes the AiContentService and calls the expand_content method.
  • Response: If successful, it returns the expanded content in JSON format; otherwise, it sends an error message.

Connecting the React Frontend to Request Expanded Content

Now that our Rails API is equipped to handle AI-generated content, use Cloving CLI to scaffold the next steps in the React frontend for making this request and displaying the expanded content.

cloving generate code --prompt "Create a function in the React PostSearch component to request expanded content for a selected post."

Cloving will generate a new function in the PostSearch component for handling this request:

// In PostSearch.js

const requestExpandedContent = async () => {
  try {
    const response = await axios.post('http://localhost:3001/api/v1/posts/expand_content', {
      content: selectedPost.content
    })
    setExpandedContent(response.data.expanded_content)
  } catch (error) {
    console.error('Error expanding content:', error)
  }
}

This function:

  • Sends a POST Request: Posts the content of the selected post to the Rails expand_content endpoint.
  • Updates State: Sets expandedContent with the AI-generated content returned by the Rails API.

Displaying the Expanded Content and Handling User Review

Finally, Cloving CLI can help scaffold code to render the AI-generated content for review and submission back to Rails.

Add a section in the PostSearch component to display expandedContent and allow users to submit it back to the Rails API.

cloving generate code --prompt "Add a form in the React component to display expanded content and submit it for saving in WordPress."

Cloving will generate a basic review component for the expanded content:

// In PostSearch.js

return (
  <div>
    {/* Existing form and post list */}
    {expandedContent && (
      <div>
        <h2>Expanded Content:</h2>
        <p>{expandedContent}</p>
        <button onClick={submitExpandedContent}>Save to WordPress</button>
      </div>
    )}
  </div>
)

In this updated component:

  • Expanded Content Display: Shows the AI-generated expanded content.
  • Save Button: Triggers submitExpandedContent, which posts the modified content back to Rails for saving in WordPress.

With Cloving CLI, this section was quickly scaffolded, allowing us to move efficiently through the process of integrating and displaying AI-generated content.


In Section 5, we’ll use Cloving CLI to finalize the workflow by implementing the save action in Rails, which will take the modified content from React and update it in WordPress. This will complete the content expansion workflow, allowing users to seamlessly expand, review, and save enhanced content directly in WordPress.


Section 5: Saving the Enhanced Content Back to WordPress Using Cloving CLI

With the AI-enhanced content ready for review in the React frontend, the final step is to allow users to submit the modified content back to the Rails backend, which will update the original WordPress post. In this section, we’ll use Cloving CLI to generate the Rails functionality required to handle this update, ensuring the content is saved back to WordPress seamlessly.


Adding the Save Endpoint in Rails

First, let’s add an endpoint in Rails that accepts the modified content from the React frontend and sends an update request to the WordPress API. Use Cloving CLI to scaffold the controller action and service code needed to perform this update.

cloving generate code --prompt "Create a Rails controller action to update a WordPress post with new content."

Cloving will generate the following code in your PostsController:

# app/controllers/api/v1/posts_controller.rb

def save_expanded_content
  post_id = params[:post_id]
  updated_content = params[:content]
  wordpress_service = WordPressService.new
  success = wordpress_service.update_post(post_id, updated_content)

  if success
    render json: { message: 'Post updated successfully' }, status: :ok
  else
    render json: { error: 'Failed to update the post on WordPress' }, status: :unprocessable_entity
  end
end

Here’s a breakdown of this action:

  • Parameters: It accepts post_id and content as parameters, representing the WordPress post ID and the modified content.
  • Service Call: Initializes WordPressService to handle the update request to WordPress.
  • Response: Sends a success message if the update succeeds, otherwise returns an error message.

Creating the WordPressService to Handle Updates

Next, let’s generate the WordPressService using Cloving CLI, which will manage the API request to update the post on WordPress.

cloving generate code --prompt "Create a Rails service to update a WordPress post with new content."

Cloving will generate a service like this:

# app/services/wordpress_service.rb
require 'httparty'

class WordPressService
  include HTTParty
  base_uri 'https://your-wordpress-site.com/wp-json/wp/v2'

  def initialize
    @headers = {
      "Content-Type" => "application/json",
      "Authorization" => "Bearer #{ENV['WORDPRESS_API_TOKEN']}"
    }
  end

  def update_post(post_id, content)
    response = self.class.put("/posts/#{post_id}", {
      headers: @headers,
      body: { content: content }.to_json
    })
    response.success?
  end
end

This WordPressService class:

  • Base URI: Sets the base URI for the WordPress API.
  • Authorization: Uses an authorization header with an API token from the environment for secure access.
  • Update Post Method: Uses an HTTP PUT request to send the updated content back to the specified post on WordPress.

Submitting the Expanded Content from React

With the Rails API ready to handle updates, let’s use Cloving CLI to scaffold a function in the React PostSearch component to submit the expanded content to Rails for saving in WordPress.

cloving generate code --prompt "Add a function in the React PostSearch component to submit expanded content to the Rails API for saving in WordPress."

Cloving will add the submitExpandedContent function in your PostSearch component:

const submitExpandedContent = async () => {
  try {
    const response = await axios.post('http://localhost:3001/api/v1/posts/save_expanded_content', {
      post_id: selectedPost.id,
      content: expandedContent
    })
    if (response.data.message) {
      alert('Post updated successfully!')
    }
  } catch (error) {
    console.error('Error saving expanded content:', error)
    alert('Failed to save the post on WordPress')
  }
}

This function:

  • Posts Data to Rails: Sends the post_id and modified content to the save_expanded_content endpoint in Rails.
  • Success Message: Displays a success message if the response is successful.
  • Error Handling: Logs errors and displays an alert if saving the content fails.

Finalizing and Testing the Workflow

With these elements in place, you can now test the full workflow:

  1. Search and Select: The user searches for and selects a WordPress post.
  2. Expand Content: The React frontend requests expanded content from the AI API via Rails.
  3. Review and Save: The user reviews the expanded content and saves it back to WordPress.

This end-to-end process, facilitated by Cloving CLI, makes it easy to set up and integrate AI-powered content workflows. The project showcases the potential of Cloving CLI in accelerating development, structuring code across multiple services, and seamlessly connecting a Rails API, React frontend, and external platforms like WordPress and AI APIs.

This setup is now a robust foundation for future enhancements, such as adding more AI features, implementing version control for drafts, or extending the frontend to allow for rich text editing. By using Cloving CLI, this development process remains streamlined, efficient, and highly adaptable to changing requirements.


Benefits of Using Cloving CLI

Streamlined Development: Cloving CLI’s generate code feature and chat mode provide real-time feedback, scaffolding, and refinement, helping you develop essential components quickly while ensuring generated code aligns with specific requirements. This rapid scaffolding frees up valuable time for testing, iteration, and fine-tuning, making the development process much faster and more efficient.

Seamless Integration Across Platforms: Cloving CLI’s versatility shines as it supports multiple AI models (OpenAI, Claude, etc.), making it easy to integrate AI-driven workflows into your preferred tools. Whether using Rails for backend management, React for the frontend, or AI services for content expansion, Cloving allows these elements to connect seamlessly, making it ideal for multi-platform applications.

Context-Aware and Task-Specific Suggestions: Cloving’s ability to retain and leverage project context means that generated code is aligned with your existing architecture and the specific needs of your app. This task-specific intelligence ensures that Cloving suggestions are not only functional but also optimized for your project’s structure and goals.


Wrapping Up

Cloving CLI is a transformative tool for developers, enabling faster, more adaptable, and efficient project creation. By combining Cloving’s context-aware code generation and interactive prompts with Rails, React, WordPress, and AI integrations, you can build robust micro apps that automate and simplify complex workflows, such as content management, in record time.

Looking ahead, Cloving’s additional features—such as automated code reviews, debugging assistance, and test generation—can further streamline your development process and improve code quality. This setup underscores the potential of AI-driven development tools like Cloving CLI to accelerate and refine the creation of sophisticated, multi-platform applications, paving the way for scalable and dynamic software solutions.