One place for hosting & domains

      Create

      How to Create a Restaurant Website (In 5 Steps)


      Running a restaurant can be both exciting and challenging. It also means you might not have a lot of time to put towards creating an online presence for your establishment. With lots of options for creating social media accounts and websites, we understand that it can be challenging to pick the right approach.

      Fortunately, Content Management Systems (CMSs) like WordPress can make it easier to combine all of your options into one beautifully-designed online space. For example, WordPress plugins and themes — think website templates — give you the flexibility to incorporate social media accounts and menus on your site, while not draining your energy and resources in the process.

      In this article, we’ll cover five steps for creating a restaurant website with WordPress. We’ll also discuss why WordPress is the best option, and how website builder tools created for the platform can take your site to the next level. Let’s jump right in!

      Make a Reservation for WordPress Hosting

      Our automatic updates and strong security defenses take server management off your hands so you can focus on dining experiences, not website details.

      Why You Should Consider WordPress for Your Restaurant Website

      Small business owners can benefit from launching their online presence with a social media platform or restaurant app, as there are many widely-available and free options. There is no denying that social media is vital to your marketing strategy but going with a third-party platform can have downsides as well.

      Three critical factors to think about when deciding whether to create a dedicated website for your restaurant include:

      • Return on Investment (ROI). While websites can be pricey, there are plans available for a broad spectrum of budgets. Once you invest the initial time required to set up a fully-functional website, it can be less of a time drain than social media in the long run.
      • Functionality and Control. You’ll want to weigh the functionality you need against the features social media platforms have to offer. While you can usually string together multiple applications, a website is more likely to provide the functionality you’ll need to create a compelling experience. Plus, you won’t be hemmed in by a third-party design; you’ll get complete control of the look and feel of your website.
      • Search Engine Optimization (SEO). Social profiles do show up in search engines, but they are a more powerful tool when used to promote content from your website. Google can’t determine the authority of a social profile, but linking back to your site can increase your overall search rankings.

      That’s why we recommend WordPress as the best CMS and website platform for your needs. Not only is it the most widely-used CMS, but it’s also a free and open-source platform. This means that the variety and diversity of plugin and theme options are nearly endless (which we’ll demonstrate shortly).

      WordPress also offers restaurant owners a lot of flexibility over who can use the website to help maintain the business’ public-facing experience. You can adjust user roles to fit your staffing structure, for example, or create content for future events and menu changes. With this platform, the sky’s the limit.

      How to Create Your Restaurant Website With WordPress (In 5 Steps)

      The best part is that getting started with WordPress is pretty simple. Often, you can install WordPress with just one click through your web host and be ready to welcome website visitors the same day. In the next few sections, we’re going to look at five essential steps to help you get your restaurant site online.

      Step 1: Choose Your Domain Name and Web Host

      Choosing a web host is the first crucial step in getting your restaurant website up and running. Your host is where all your site’s data, files, and media will be stored and maintained.

      There are a few things to consider when choosing your host, however. You’ll want to compare what each provider is offering with what you think you’ll need over the first year of running your site. This includes:

      • Security. A website crash on a Friday night can mean a loss of business if your customers expect to see your new menu each week. Reviewing potential web hosts to understand the security features they offer is key to keeping your site up and running. Backup and restoration options are a good place to start.
      • Software. If you need to get your restaurant site online fast, partnering with a host that offers easy software options can be a big help. Be sure to find out whether your host offers one-click options for additional software or provides features for speed and optimization.
      • Support. Web hosts typically offer increasing levels of support as you upgrade to higher-tier plans. You’ll want to decide if you need 24/7 expert support or if you can wait for a ticket to be answered.
      • Extras. You might find it hard to choose between several high-quality web hosts. If that’s the case, you can take a close look at what extras each host offers. If you know you could benefit from premium themes, pre-installed eCommerce options, or site builders, for example, reviewing these options might be a good way to break a tie.

      No matter what type of hosting you ultimately decide you need, here at DreamHost we offer a wide range of WordPress plans.

      WordPress hosting at DreamHost.

      Once you have a host picked out, you get to decide on a name for your new website. Some best practices might be helpful in this process. While a .com is still the most recognized and respected top-level domain out there, there are plenty of other options. The most important thing is to make sure your domain is short and memorable.

      DreamHost's domain name search page.

      Another factor to keep in mind is the extra goodies that might come with your hosting plan. Some hosts offer free add-ons, for example. Here at DreamHost, we’re excited to be able to provide access to a handy site builder tool.

      To get started, you’ll need to select “WP Website Builder” as an option during checkout of your DreamHost plan purchase. Then, we’ll automatically install WordPress and premium website builder plugins for WordPress — Inspirations and Page & Post Builder — built by our friends at BoldGrid.

      Step 2: Install a Dedicated Restaurant Theme

      Once you choose a host and set up your site at its domain name, you can start thinking about website design.

      WP Website Builder brings easy drag-and-drop page building to your WordPress site, along with plenty of theme options to choose from. To select one, you’ll navigate to the Inspirations menu. There, you can easily select a new theme by clicking on Start Over with New Inspiration.

      The Inspirations page.

      If you’re new to WordPress, this is the first page you’ll see when you visit your dashboard. You’ll then be led through several steps that will get you started with your new theme.

      First, you’ll select the category of themes you want to browse. We’ll pick Restaurant, naturally.

      The design tab with theme category options.

      You’ll see that there are many options to choose from. For this demonstration, we’ll try out the Florentine theme.

      Page options for the Florentine theme.

      After you select your theme, the next page will provide some options for testing its responsiveness on various screen sizes. You can also select how many pre-set pages you want to start with. We’ve chosen the Kitchen Sink option with blog functionality, so we can experiment with everything.

      Once you make your changes here, you’ll click on the Next button.

      Content options for the theme.

      Your final step in the setup process will be to fill out some optional but helpful information. This is found in the Essentials tab. You can edit this information later, but it will be used throughout your website to pre-populate your contact and social media information.

      The Essential information tab

      Be sure to select Finish and Install when you’re done. After that, WP Website Builder will automatically install additional plugins to help support the theme you chose. Once that’s complete, you can add your restaurant logo and really start cooking.

      Step 3: Select Plugins to Expand Your Site’s Feature Set

      While WP Website Builder includes several plugins that offer enhanced functionality for creating your restaurant site, you might want to explore a few other tools as well. Plugins, true to their name, plug right into your WordPress site and theme to extend their existing options.

      The WordPress plugin directory.

      Whether you plan on offering new menu items every week, only on holidays, or whenever you feel like it, plugins can help you manage those changes. Additionally, other plugins can help you develop an online reservation system or organize in-house events.

      One plugin to check out is Five Star Restaurant Reservations.

      The Restaurant Reservations plugin banner.

      This solution is packed with features to help you manage all aspects of taking online reservations and table bookings. You can accept, reject, or block reservations as needed. Additionally, you can set up specific user roles for your staff and send notifications to customers.

      Step 4: Create Engaging Content

      Once you have your design in place, you’ll want to solidify the content strategy for your restaurant.

      Whether you choose to feature blog content, exciting menus, or just pictures of your tasty-looking food, WordPress has you covered. Even the rotisserie giant, Boston Market, uses WordPress for its restaurant website.

      The Boston Market WordPress website.

      There are several ways to do this, including various options within the WordPress Edit Post area. Additionally, you can check out a plugin like WP Scheduled Posts.

      The WP Scheduled Posts plugin banner

      This tool can help you create an editorial calendar to keep your blog fresh and up-to-date. That way, you won’t have to worry about forgetting to post a timely article or showcasing outdated content.

      Once you establish your approach to content, you might want to turn to social media channels to spread the news about your new website.

      Step 5: Build an Email List

      Building up a loyal clientele can take some time. Creating the opportunity for potential customers to sign up to an email list can be a smart strategy. Using and maintaining an email list for your restaurant gives you a direct link to your customers. You can send menu announcements, hours of operation updates, and discount offers.

      There are a lot of great marketing tools available. MailChimp is a popular email newsletter and list management service. You’ll need to create a free account, and then there’s a plugin available that can connect your site up to this service instantly.

      With MailChimp, you can fully integrate your WordPress site with your email marketing campaigns. That way, you can bring in as many new patrons as possible.

      Be Awesome on the Internet

      Join our monthly newsletter for tips and tricks to build your dream website!

      Growing and Promoting Your Restaurant Website

      At this point, your site is all set up. So, how do you get the word out about it? Here’s where your WordPress site and social media can combine to create a powerful team.

      There are several key items to keep in mind that can help you promote your new website on social media, including:

      • Micro-influencers. This might be easier if your business operates in a more metropolitan area. Social media influencers can promote your site for you, and expose it to a new audience. Additionally, inviting food bloggers to your restaurant can also pay off.
      • Reviews. Opening up review options online and collecting testimonials from social media comments or in-restaurant surveys is one of the best techniques available to you. Posting these reviews to your website can be an effective marketing tool.
      • Social media management apps. Keeping track of several social media accounts can be a time sink. Fortunately, there are plenty of management techniques and applications for social media that can help. We recommend checking out Hootsuite first, as it connects to all the major social media channels.

      Tapping into the power of word-of-mouth marketing through online social channels, hashtags, and lots of linking back to your new website may seem daunting at first, but should pay off in the long run.

      The Last Bite

      The restaurant business can be competitive. Along with tasty food and creative dishes, customers are looking for an experience that often goes beyond the time they spend in your physical establishment. Creating a standout restaurant website design can help them feel more connected to your business and keep them coming back for more.

      Here at DreamHost, we want you to be able to put your energy into making delicious meals, and not worry about whether your website maintenance and support is taken care of. That’s why we offer complete WordPress hosting solutions, now served with a side of our premium website builder tools, so you can focus on making Instagram-worthy food!



      Source link

      How to Create a Media Kit for Your Website (5 Key Tips)


      You’ve built a great website and spent hours crafting content that’s laser-focused on your target audience. Your traffic is great, the site design is impeccable, and the search engine optimization? You’re hitting every keyword, baby.

      But here’s the unpleasant truth: you can be doing all those things right and still not get the interest from advertisers and media outlets that you want to grow your business.

      You may be wondering what you can do to turn things around and deliver a comprehensive message to prospects about your services.

      Adding your business’ key information to your website can be a way to maintain your brand standards while bringing in new advertisers and collaborators. Collecting these details into a “media kit” can help you provide a convenient place for people to find and use them as needed.

      In this article, we’ll take a look at how media kits coordinate with your other content and why you might want to add one to your site. Along the way, we’ll share some stellar media kit examples. We’ll also go over how to create your own media kit in five easy steps.

      Whether you’re a blogger, influencer, or entrepreneur, creating a media kit for your website is a must. Let’s get you some press coverage!

      Shared Hosting That Powers Your Purpose

      We make sure your website is fast, secure and always up so your visitors trust you. Plans start at $2.59/mo.

      What a Media Kit Typically Provides

      The terms “press kit” and “media kit” are often used interchangeably. A media kit, however, is more specifically geared towards bringing in advertisers or potential clients.

      Arguably, a public relations-driven press kit can also bring in advertisers. For this article, we’re going to use the term “media kit,” however, and focus on how it can help you monetize your website, bring in collaborators, and appeal to advertisers.

      A comprehensive media kit generally includes the following:

      • An introduction. You can use this as an opportunity to present a very targeted message about your business. Alternatively, you can produce an approved bio for anyone to use.
      • Site statistics. There’s no need to be humble here — it’s smart to put your best numbers out in front. For example, you can let everyone know what a great opportunity your site presents due to the volume of traffic it receives.
      • Advertising opportunities. You can use your media kit to spell out precisely what kind of advertising you have available on your site. Your media kit is a good place to outline what you can’t accommodate as well.
      • Audience data. The demographics of your site’s audience might not be right for every advertiser or collaborator. Supplying that information in your media kit can help eliminate any confusion.

      Let’s look at an online-only media outlet as an example. The popular website, BuzzFeed, has a global audience of over 650 million. It showcases its media kit information in a clean and scrollable format for potential advertisers. The kit clearly displays the most critical information and allows for opportunities to click through and learn more.

      Alternatively, Catherine Summers is a style blogger with a media kit that ticks off all the best practices boxes. Summers immediately jumps in and addresses why anyone would want to work with her and then lays out all the options.

      Catherine Summers’ media kit page featuring her headshot.

      These examples showcase a wide variety of different approaches you might consider for your own media kit.

      Why You Might Want to Consider Adding a Media Kit to Your Website

      As we mentioned before, media kits are prime real estate for showcasing the best of what you have to offer. Plus, you can plainly state how interested advertisers or other potential clients can work with you.

      That said, there are are two main audiences to think about when deciding whether you should create a media kit for your website. They include:

      • Advertisers. If you are hoping to bring in revenue by offering up space on your website, you’ll want to consider crafting your media kit with an appeal to potential advertisers. Highlighting your audience demographics and the number of views they might get on your site are important metrics to consider.
      • Clients. If your primary goal is to bring in new clients or fill out your speaking engagement calendar, there might be other aspects to highlight in your kit as well. For instance, showcasing previous high-profile engagements can heighten your appeal to potential clients.

      Understanding the primary goal of creating a media kit for your website can help you prioritize your content and focus your efforts. Of course, your media kit might also have a combination of advertiser and client appeal. As we saw in the examples above, being comprehensive with your media kit is definitely a valid approach.

      Be Awesome on the Internet

      Join our monthly newsletter for tips and tricks to build your dream website!

      How to Create a Media Kit for Your Website (5 Key Tips)

      Now that you have some idea of what a media kit might include, let’s discuss how you can start building your own. In the following sections, we’ll cover five essential steps that will get you on the path to building an attention-grabbing kit.

      1. Establish Your Brand

      When it comes to marketing, brand and brand strategy are vital. Your media kit is one opportunity to really solidify your brand and make sure it’s represented correctly. There are several ways you can help to establish your brand with your media kit.

      Providing downloadable documents, press releases, images, and logos or graphics is one approach. Offering these can help encourage site visitors to use your products and establish a friendly atmosphere. Visitors will know it’s OK to use the materials, and you control their quality.

      A downloadable biography and images in Brene Brown’s media kit.

      Another element you might consider including in your media kit is a style guide. This guide may take some investment of time to create but can pay off in the long run. A style guide makes it very clear how your brand can and should be used both on- and offline.

      2. Provide Relevant Statistics

      We mentioned earlier that one element of a media kit to consider is statistics about your site and business. Depending on your level of experience with tracking analytics, this might seem challenging at first.

      If you’re using a managed web host for your website, you might want to see if it provides easily-accessible statistics. For example, here at DreamHost, all of our hosting accounts include user statistics functionality. This can help you track visitor numbers, traffic to your domain, and even referring URLs.

      BuzzFeed’s advertiser information page featuring audience statistics.

      To maximize the benefit of providing your stats, you’ll want to keep in mind who they’re relevant to. In the case of media kits, you’re not really providing these numbers for your readers, but rather for potential advertisers or clients. Therefore, you’ll want to focus on the figures that illustrate the benefits of working with you and your audience. Don’t forget to include follower demographics and engagement data from your social media platforms too!

      3. Describe How to Collaborate With You

      Your media kit is also a place where you can specifically outline what opportunities you are looking for when it comes to collaboration, such as:

      • Affiliate Marketing Opportunities
      • Book Deal
      • Event Appearances
      • Giveaways
      • Guest Posting
      • Podcast Sponsorships
      • Product Reviews
      • Site Ads
      • Social Media Promotions
      • Sponsored Blog Posts

      Being specific can help increase the number of quality leads you get. For example, if you are primarily looking for guest posting or social media opportunities, outline the specifics in your media kit.

      The LadyBossBlogger website has an excellent example of how to present your collaboration suggestions and opportunities transparently.

      LadyBossBlogger’s media kit page featuring collaboration information

      Alternatively, you can create forms that allow potential collaborators to give information and outline their inquiries. You’ll also want to consider whether you want to list your prices upfront or encourage prospects to contact you for more details.

      4. Share What Others Have to Say About You

      Testimonials are used in marketing all the time and for good reason. Your media kit can leverage the power of these as well. As a form of word-of-mouth marketing, collecting strong testimonials (or just creating a list of past media coverage) is often a worthwhile investment of time.

      Whether you’re citing past media mentions from publications or sharing sound bites from social media followers, It’s always advisable to note in your media kit exactly where your testimonials are coming from. You can help build trust through transparency in this way.

      One useful example to check out is cookbook author Ren Behan’s press site. There, she displays comments and testimonials in a variety of ways.

      Testimonials from Ren Behan’s media kit page.

      There are several methods for collecting testimonials. You can use online reviews and LinkedIn recommendations, for example. However you decide to obtain them, you’ll want to make sure it is evident in your media kit whether it is acceptable for others (such as reporters) to use them.

      5. Provide Your Contact Information

      It may seem like a simple thing, but providing your contact information is extremely vital. In fact, the contact page is often the most-visited page on any website. You can link to this page in your media kit or simply include contact information and methods within it.

      Either way, providing multiple contact options is always a smart approach. Some web users prefer forms, while others will just want to know what your email address is. One good example of combining both methods comes from (not surprisingly) a UX designer’s website.

      The contact information on Ekkrit Design’s website.

      The simple approach here makes critical information very clear and gives the visitor options. Your contact information is probably not where you want to implement an online scavenger hunt. Also, it’s essential to always keep this information up-to-date, with all links and forms functioning optimally.

      Essential Tools and Resources for Building Your Media Kit

      Now that you’re armed with some great ideas for your media kit, you might be wondering how to create yours. You can do this entirely from scratch, of course. However, there are also quite a few free and premium resources that can make the process easier.

      These include:

      • Canva. This is an online design tool with beautiful pre-made templates and graphic elements. You can get a free template with limited access or pay to get a variety of upgrades at reasonable prices.
      • Creative Market. An online exchange for creative work, Creative Market is like Etsy for marketing materials. You can commission a custom font, or browse other original work to find the perfect fit for your brand.
      • WordPress. There are many options out there for building websites, but at DreamHost, we’re partial to WordPress. As a free, open-source tool, it offers immense flexibility. Plus, you’ll find many useful plugins for creating portfolios, displaying contact information, and developing contact forms.

      Ultimately, how you create your media kit is less important than what it includes. So you should feel free to use whatever tools you’re most comfortable with and focus on ensuring that your kit is comprehensive, easy to understand, and user-friendly.

      Get Those Media Contacts

      Bloggers, influencers, small business owners — regardless of your focus, you want to solidify your brand, bring in more work, and attract advertisers. For all those goals, a media kit is the key.

      Now that we’ve covered the ins and outs of media kits and shared some industry-standard examples, you should be ready to launch your electronic press kit.

      Creating a wow-inducing media kit can take time. Here at DreamHost, we want you to be able to focus on the task at hand, and not get sidetracked by website maintenance and troubleshooting. That’s why we offer complete hosting solutions with reliable support, so you can focus on growing your business!



      Source link

      How To Create Nested Resources for a Ruby on Rails Application


      Introduction

      Ruby on Rails is a web application framework written in Ruby that offers developers an opinionated approach to application development. Working with Rails gives developers:

      • Conventions for handling things like routing, stateful data, and asset management.
      • A firm grounding in the model-view-controller (MCV) architectural pattern, which separates an application’s logic, located in models, from the presentation and routing of application information.

      As you add complexity to your Rails applications, you will likely work with multiple models, which represent your application’s business logic and interface with your database. Adding related models means establishing meaningful relationships between them, which then affect how information gets relayed through your application’s controllers, and how it is captured and presented back to users through views.

      In this tutorial, you will build on an existing Rails application that offers users facts about sharks. This application already has a model for handling shark data, but you will add a nested resource for posts about individual sharks. This will allow users to build out a wider body of thoughts and opinions about individual sharks.

      Prerequisites

      To follow this tutorial, you will need:

      • A local machine or development server running Ubuntu 18.04. Your development machine should have a non-root user with administrative privileges and a firewall configured with ufw. For instructions on how to set this up, see our Initial Server Setup with Ubuntu 18.04 tutorial.
      • Node.js and npm installed on your local machine or development server. This tutorial uses Node.js version 10.16.3 and npm version 6.9.0. For guidance on installing Node.js and npm on Ubuntu 18.04, follow the instructions in the “Installing Using a PPA” section of How To Install Node.js on Ubuntu 18.04.
      • Ruby, rbenv, and Rails installed on your local machine or development server, following Steps 1-4 in How To Install Ruby on Rails with rbenv on Ubuntu 18.04. This tutorial uses Ruby 2.5.1, rbenv 1.1.2, and Rails 5.2.3.
      • SQLite installed, and a basic shark information application created, following the directions in How To Build a Ruby on Rails Application.

      Step 1 — Scaffolding the Nested Model

      Our application will take advantage of Active Record associations to build out a relationship between Shark and Post models: posts will belong to particular sharks, and each shark can have multiple posts. Our Shark and Post models will therefore be related through belongs_to and has_many associations.

      The first step to building out the application in this way will be to create a Post model and related resources. To do this, we can use the rails generate scaffold command, which will give us a model, a database migration to alter the database schema, a controller, a full set of views to manage standard Create, Read, Update, and Delete (CRUD) operations, and templates for partials, helpers, and tests. We will need to modify these resources, but using the scaffold command will save us some time and energy since it generates a structure we can use as a starting point.

      First, make sure that you are in the sharkapp directory for the Rails project that you created in the prerequisites:

      Create your Post resources with the following command:

      • rails generate scaffold Post body:text shark:references

      With body:text, we’re telling Rails to include a body field in the posts database table — the table that maps to the Post model. We’re also including the :references keyword, which sets up an association between the Shark and Post models. Specifically, this will ensure that a foreign key representing each shark entry in the sharks database is added to the posts database.

      Once you have run the command, you will see output confirming the resources that Rails has generated for the application. Before moving on, you can check your database migration file to look at the relationship that now exists between your models and database tables. Use the following command to look at the contents of the file, making sure to substitute the timestamp on your own migration file for what’s shown here:

      • cat db/migrate/20190805132506_create_posts.rb

      You will see the following output:

      Output

      class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.text :body t.references :shark, foreign_key: true t.timestamps end end end

      As you can see, the table includes a column for a shark foreign key. This key will take the form of model_name_id — in our case, shark_id.

      Rails has established the relationship between the models elsewhere as well. Take a look at the newly generated Post model with the following command:

      Output

      class Post < ApplicationRecord belongs_to :shark end

      The belongs_to association sets up a relationship between models in which a single instance of the declaring model belongs to a single instance of the named model. In the case of our application, this means that a single post belongs to a single shark.

      In addition to setting this relationship, the rails generate scaffold command also created routes and views for posts, as it did for our shark resources in Step 3 of How To Build a Ruby on Rails Application.

      This is a useful start, but we will need to configure some additional routing and solidify the Active Record association for the Shark model in order for the relationship between our models and routes to work as desired.

      Step 2 — Specifying Nested Routes and Associations for the Parent Model

      Rails has already set the belongs_to association in our Post model, thanks to the :references keyword in the rails generate scaffold command, but in order for that relationship to function properly we will need to specify a has_many association in our Shark model as well. We will also need to make changes to the default routing that Rails gave us in order to make post resources the children of shark resources.

      To add the has_many association to the Shark model, open app/models/shark.rb using nano or your favorite editor:

      Add the following line to the file to establish the relationship between sharks and posts:

      ~/sharkapp/app/models/shark.rb

      class Shark < ApplicationRecord
        has_many :posts
        validates :name, presence: true, uniqueness: true
        validates :facts, presence: true
      end
      

      One thing that is worth thinking about here is what happens to posts once a particular shark is deleted. We likely do not want the posts associated with a deleted shark persisting in the database. To ensure that any posts associated with a given shark are eliminated when that shark is deleted, we can include the dependent option with the association.

      Add the following code to the file to ensure that the destroy action on a given shark deletes any associated posts:

      ~/sharkapp/app/models/post.rb

      class Shark < ApplicationRecord
        has_many :posts , dependent: :destroy
        validates :name, presence: true, uniqueness: true
        validates :facts, presence: true
      end
      

      Once you have finished making these changes, save and close the file. If you are using nano, you can do this by pressing CTRL+X, Y, then ENTER.

      Next, open your config/routes.rb file to modify the relationship between your resourceful routes:

      Currently, the file looks like this:

      ~/sharkapp/config/routes.rb

      Rails.application.routes.draw do
        resources :posts 
        resources :sharks
      
        root 'sharks#index'
        # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
      end
      

      The current code establishes an independent relationship between our routes, when what we would like to express is a dependent relationship between sharks and their associated posts.

      Let’s update our route declaration to make :sharks the parent of :posts. Update the code in the file to look like the following:

      ~/sharkapp/config/routes.rb

      Rails.application.routes.draw do
        resources :sharks do
          resources :posts
        end
        root 'sharks#index'
        # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
      end
      

      Save and close the file when you are finished editing.

      With these changes in place, you can move on to updating your posts controller.

      Step 3 — Updating the Posts Controller

      The association between our models gives us methods that we can use to create new post instances associated with particular sharks. To use these methods, we will need to add them our posts controller.

      Open the posts controller file:

      • nano app/controllers/posts_controller.rb

      Currently, the file looks like this:

      ~/sharkapp/controllers/posts_controller.rb

      class PostsController < ApplicationController
        before_action :set_post, only: [:show, :edit, :update, :destroy]
      
        # GET /posts
        # GET /posts.json
        def index
          @posts = Post.all
        end
      
        # GET /posts/1
        # GET /posts/1.json
        def show
        end
      
        # GET /posts/new
        def new
          @post = Post.new
        end
      
        # GET /posts/1/edit
        def edit
        end
      
        # POST /posts
        # POST /posts.json
        def create
          @post = Post.new(post_params)
      
          respond_to do |format|
            if @post.save
              format.html { redirect_to @post, notice: 'Post was successfully created.' }
              format.json { render :show, status: :created, location: @post }
            else
              format.html { render :new }
              format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      
        # PATCH/PUT /posts/1
        # PATCH/PUT /posts/1.json
        def update
          respond_to do |format|
            if @post.update(post_params)
              format.html { redirect_to @post, notice: 'Post was successfully updated.' }
              format.json { render :show, status: :ok, location: @post }
            else
              format.html { render :edit }
              format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      
        # DELETE /posts/1
        # DELETE /posts/1.json
        def destroy
          @post.destroy
          respond_to do |format|
            format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
            format.json { head :no_content }
          end
        end
      
        private
          # Use callbacks to share common setup or constraints between actions.
          def set_post
            @post = Post.find(params[:id])
          end
      
          # Never trust parameters from the scary internet, only allow the white list through.
          def post_params
            params.require(:post).permit(:body, :shark_id)
          end
      end
      

      Like our sharks controller, this controller’s methods work with instances of the associated Post class. For example, the new method creates a new instance of the Post class, the index method grabs all instances of the class, and the set_post method uses find and params to select a particular post by id. If, however, we want our post instances to be associated with particular shark instances, then we will need to modify this code, since the Post class is currently operating as an independent entity.

      Our modifications will make use of two things:

      • The methods that became available to us when we added the belongs_to and has_many associations to our models. Specifically, we now have access to the build method thanks to the has_many association we defined in our Shark model. This method will allow us to create a collection of post objects associated with a particular shark object, using the shark_id foreign key that exists in our posts database.
      • The routes and routing helpers that became available when we created a nested posts route. For a full list of example routes that become available when you create nested relationships between resources, see the Rails documentation. For now, it will be enough for us to know that for each specific shark — say sharks/1 — there will be an associated route for posts related to that shark: sharks/1/posts. There will also be routing helpers like shark_posts_path(@shark) and edit_sharks_posts_path(@shark) that refer to these nested routes.

      In the file, we’ll begin by writing a method, get_shark, that will run before each action in the controller. This method will create a local @shark instance variable by finding a shark instance by shark_id. With this variable available to us in the file, it will be possible to relate posts to a specific shark in the other methods.

      Above the other private methods at the bottom of the file, add the following method:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
      private
        def get_shark
          @shark = Shark.find(params[:shark_id])
        end
        # Use callbacks to share common setup or constraints between actions.
      . . . 
      

      Next, add the corresponding filter to the top of the file, before the existing filter:

      ~/sharkapp/controllers/posts_controller.rb

      class PostsController < ApplicationController
        before_action :get_shark
      

      This will ensure that get_shark runs before each action defined in the file.

      Next, you can use this @shark instance to rewrite the index method. Instead of grabbing all instances of the Post class, we want this method to return all post instances associated with a particular shark instance.

      Modify the index method to look like this:

      ~/sharkapp/controllers/posts_controller.rb

      . . .
        def index
          @posts = @shark.posts
        end
      . . .
      

      The new method will need a similar revision, since we want a new post instance to be associated with a particular shark. To achieve this, we can make use of the build method, along with our local @shark instance variable.

      Change the new method to look like this:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
        def new
          @post = @shark.posts.build
        end
      . . . 
      

      This method creates a post object that’s associated with the specific shark instance from the get_shark method.

      Next, we’ll address the method that’s most closely tied to new: create. The create method does two things: it builds a new post instance using the parameters that users have entered into the new form, and, if there are no errors, it saves that instance and uses a route helper to redirect users to where they can see the new post. In the case of errors, it renders the new template again.

      Update the create method to look like this:

      ~/sharkapp/controllers/posts_controller.rb

        def create
          @post = @shark.posts.build(post_params)
      
              respond_to do |format|
               if @post.save  
                  format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
                  format.json { render :show, status: :created, location: @post }
               else
                  format.html { render :new }
                  format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      

      Next, take a look at the update method. This method uses a @post instance variable, which is not explicitly set in the method itself. Where does this variable come from?

      Take a look at the filters at the top of the file. The second, auto-generated before_action filter provides an answer:

      ~/sharkapp/controllers/posts_controller.rb

      class PostsController < ApplicationController
        before_action :get_shark
        before_action :set_post, only: [:show, :edit, :update, :destroy]
        . . .
      

      The update method (like show, edit, and destroy) takes a @post variable from the set_post method. That method, listed under the get_shark method with our other private methods, currently looks like this:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
      private
      . . . 
        def set_post
          @post = Post.find(params[:id])
        end
      . . .
      

      In keeping with the methods we’ve used elsewhere in the file, we will need to modify this method so that @post refers to a particular instance in the collection of posts that’s associated with a particular shark. Keep the build method in mind here — thanks to the associations between our models, and the methods (like build) that are available to us by virtue of those associations, each of our post instances is part of a collection of objects that’s associated with a particular shark. So it makes sense that when querying for a particular post, we would query the collection of posts associated with a particular shark.

      Update set_post to look like this:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
      private
      . . . 
        def set_post
          @post = @shark.posts.find(params[:id])
        end
      . . .
      

      Instead of finding a particular instance of the entire Post class by id, we instead search for a matching id in the collection of posts associated with a particular shark.

      With that method updated, we can look at the update and destroy methods.

      The update method makes use of the @post instance variable from set_post, and uses it with the post_params that the user has entered in the edit form. In the case of success, we want Rails to send the user back to the index view of the posts associated with a particular shark. In the case of errors, Rails will render the edit template again.

      In this case, the only change we will need to make is to the redirect_to statement, to handle successful updates. Update it to redirect to shark_post_path(@shark), which will redirect to the index view of the selected shark’s posts:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
        def update
          respond_to do |format|
            if @post.update(post_params)
              format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
              format.json { render :show, status: :ok, location: @post }
            else
              format.html { render :edit }
              format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      . . .
      

      Next, we will make a similar change to the destroy method. Update the redirect_to method to redirect requests to shark_posts_path(@shark) in the case of success:

      ~/sharkapp/controllers/posts_controller.rb

      . . . 
        def destroy
          @post.destroy
           respond_to do |format|
            format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
            format.json { head :no_content }
          end
        end
      . . .
      

      This is the last change we will make. You now have a posts controller file that looks like this:

      ~/sharkapp/controllers/posts_controller.rb

      class PostsController < ApplicationController
        before_action :get_shark
        before_action :set_post, only: [:show, :edit, :update, :destroy]
      
        # GET /posts
        # GET /posts.json
        def index
          @posts = @shark.posts
        end
      
        # GET /posts/1
        # GET /posts/1.json
        def show
        end
      
        # GET /posts/new
        def new
          @post = @shark.posts.build
        end
      
        # GET /posts/1/edit
        def edit
        end
      
        # POST /posts
        # POST /posts.json
        def create
          @post = @shark.posts.build(post_params)
      
              respond_to do |format|
               if @post.save  
                  format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
                  format.json { render :show, status: :created, location: @post }
               else
                  format.html { render :new }
                  format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      
        # PATCH/PUT /posts/1
        # PATCH/PUT /posts/1.json
        def update
          respond_to do |format|
            if @post.update(post_params)
              format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
              format.json { render :show, status: :ok, location: @post }
            else
              format.html { render :edit }
              format.json { render json: @post.errors, status: :unprocessable_entity }
            end
          end
        end
      
        # DELETE /posts/1
        # DELETE /posts/1.json
        def destroy
          @post.destroy
          respond_to do |format|
            format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
            format.json { head :no_content }
          end
        end
      
        private
      
         def get_shark
           @shark = Shark.find(params[:shark_id])
         end
          # Use callbacks to share common setup or constraints between actions.
          def set_post
            @post = @shark.posts.find(params[:id])
          end
      
          # Never trust parameters from the scary internet, only allow the white list through.
          def post_params
            params.require(:post).permit(:body, :shark_id)
          end
      end
      

      The controller manages how information is passed from the view templates to the database and vice versa. Our controller now reflects the relationship between our Shark and Post models, in which posts are associated with particular sharks. We can move on to modifying the view templates themselves, which are where users will pass in and modify post information about particular sharks.

      Step 4 — Modifying Views

      Our view template revisions will involve changing the templates that relate to posts, and also modifying our sharks show view, since we want users to see the posts associated with particular sharks.

      Let’s start with the foundational template for our posts: the form partial that is reused across multiple post templates. Open that form now:

      • nano app/views/posts/_form.html.erb

      Rather than passing only the post model to the form_with form helper, we will pass both the shark and post models, with post set as a child resource.

      Change the first line of the file to look like this, reflecting the relationship between our shark and post resources:

      ~/sharkapp/views/posts/_form.html.erb

      <%= form_with(model: [@shark, post], local: true) do |form| %>
      . . . 
      

      Next, delete the section that lists the shark_id of the related shark, since this is not essential information in the view.

      The finished form, complete with our edits to the first line and without the deleted shark_id section, will look like this:

      ~/sharkapp/views/posts/_form.html.erb

      <%= form_with(model: [@shark, post], local: true) do |form| %>
        <% if post.errors.any? %>
          <div id="error_explanation">
            <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
      
            <ul>
            <% post.errors.full_messages.each do |message| %>
              <li><%= message %></li>
            <% end %>
            </ul>
          </div>
        <% end %>
      
        <div class="field">
          <%= form.label :body %>
          <%= form.text_area :body %>
        </div>
      
        <div class="actions">
          <%= form.submit %>
        </div>
      <% end %>
      

      Save and close the file when you are finished editing.

      Next, open the index view, which will show the posts associated with a particular shark:

      • nano app/views/posts/index.html.erb

      Thanks to the rails generate scaffold command, Rails has generated the better part of the template, complete with a table that shows the body field of each post and its associated shark.

      Much like the other code we have already modified, however, this template treats posts as independent entities, when we would like to make use of the associations between our models and the collections and helper methods that these associations give us.

      In the body of the table, make the following updates:

      First, update post.shark to post.shark.name, so that the table will include the name field of the associated shark, rather than identifying information about the shark object itself:

      ~/sharkapp/app/views/posts/index.html.erb

      . . . 
        <tbody>
          <% @posts.each do |post| %>
            <tr>
              <td><%= post.body %></td>
              <td><%= post.shark.name %></td>
      . . . 
      

      Next, change the Show redirect to direct users to the show view for the associated shark, since they will most likely want a way to navigate back to the original shark. We can make use of the @shark instance variable that we set in the controller here, since Rails makes instance variables created in the controller available to all views. We’ll also change the text for the link from Show to Show Shark, so that users will better understand its function.

      Update the this line to the following:

      ~/sharkapp/app/views/posts/index.html.erb

      . . . 
        <tbody>
          <% @posts.each do |post| %>
            <tr>
              <td><%= post.body %></td>
              <td><%= post.shark.name %></td>
              <td><%= link_to 'Show Shark', [@shark] %></td>
      

      In the next line, we want to ensure that users are routed the right nested path when they go to edit a post. This means that rather than being directed to posts/post_id/edit, users will be directed to sharks/shark_id/posts/post_id/edit. To do this, we’ll use the shark_post_path routing helper and our models, which Rails will treat as URLs. We’ll also update the link text to make its function clearer.

      Update the Edit line to look like the following:

      ~/sharkapp/app/views/posts/index.html.erb

      . . . 
        <tbody>
          <% @posts.each do |post| %>
            <tr>
              <td><%= post.body %></td>
              <td><%= post.shark.name %></td>
              <td><%= link_to 'Show Shark', [@shark] %></td>
              <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
      

      Next, let’s add a similar change to the Destroy link, updating its function in the string, and adding our shark and post resources:

      ~/sharkapp/app/views/posts/index.html.erb

      . . . 
        <tbody>
          <% @posts.each do |post| %>
            <tr>
              <td><%= post.body %></td>
              <td><%= post.shark.name %></td>
              <td><%= link_to 'Show Shark', [@shark] %></td>
              <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
              <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
      

      Finally, at the bottom of the form, we will want to update the New Post path to take users to the appropriate nested path when they want to create a new post. Update the last line of the file to make use of the new_shark_post_path(@shark) routing helper:

      ~/sharkapp/app/views/posts/index.html.erb

      . . . 
      <%= link_to 'New Post', new_shark_post_path(@shark) %>
      

      The finished file will look like this:

      ~/sharkapp/app/views/posts/index.html.erb

      <p id="notice"><%= notice %></p>
      
      <h1>Posts</h1>
      
      <table>
        <thead>
          <tr>
            <th>Body</th>
            <th>Shark</th>
            <th colspan="3"></th>
          </tr>
        </thead>
      
        <tbody>
          <% @posts.each do |post| %>
            <tr>
              <td><%= post.body %></td>
              <td><%= post.shark.name %></td>
              <td><%= link_to 'Show Shark', [@shark] %></td>
              <td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
              <td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
            </tr>
          <% end %>
        </tbody>
      </table>
      
      <br>
      
      <%= link_to 'New Post', new_shark_post_path(@shark) %>
      

      Save and close the file when you are finished editing.

      The other edits we will make to post views won’t be as numerous, since our other views use the form partial we have already edited. However, we will want to update the link_to references in the other post templates to reflect the changes we have made to our form partial.

      Open app/views/posts/new.html.erb:

      • nano app/views/posts/new.html.erb

      Update the link_to reference at the bottom of the file to make use of the shark_posts_path(@shark) helper:

      ~/sharkapp/app/views/posts/new.html.erb

      . . . 
      <%= link_to 'Back', shark_posts_path(@shark) %>
      

      Save and close the file when you are finished making this change.

      Next, open the edit template:

      • nano app/views/posts/edit.html.erb

      In addition to the Back path, we’ll update Show to reflect our nested resources. Change the last two lines of the file to look like this:

      ~/sharkapp/app/views/posts/edit.html.erb

      . . . 
      <%= link_to 'Show', [@shark, @post] %> |
      <%= link_to 'Back', shark_posts_path(@shark) %>
      

      Save and close the file.

      Next, open the show template:

      • nano app/views/posts/show.html.erb

      Make the following edits to the Edit and Back paths at the bottom of the file:

      ~/sharkapp/app/views/posts/edit.html.erb

      . . .
      <%= link_to 'Edit', edit_shark_post_path(@shark, @post) %> |
      <%= link_to 'Back', shark_posts_path(@shark) %>
      

      Save and close the file when you are finished.

      As a final step, we will want to update the show view for our sharks so that posts are visible for individual sharks. Open that file now:

      • nano app/views/sharks/show.html.erb

      Our edits here will include adding a Posts section to the form and an Add Post link at the bottom of the file.

      Below the Facts for a given shark, we will add a new section that iterates through each instance in the collection of posts associated with this shark, outputting the body of each post.

      Add the following code below the Facts section of the form, and above the redirects at the bottom of the file:

      ~/sharkapp/app/views/sharks/show.html.erb

      . . .
      <p>
        <strong>Facts:</strong>
        <%= @shark.facts %>
      </p>
      
      <h2>Posts</h2>
      <% for post in @shark.posts %>
          <ul>
            <li><%= post.body %></li>
        </ul>
      <% end %>
      
      <%= link_to 'Edit', edit_shark_path(@shark) %> |
      . . . 
      

      Next, add a new redirect to allow users to add a new post for this particular shark:

      ~/sharkapp/app/views/sharks/show.html.erb

      . . .
      <%= link_to 'Edit', edit_shark_path(@shark) %> |
      <%= link_to 'Add Post', shark_posts_path(@shark) %> |
      <%= link_to 'Back', sharks_path %>
      

      Save and close the file when you are finished editing.

      You have now made changes to your application’s models, controllers, and views to ensure that posts are always associated with a particular shark. As a final step, we can add some validations to our Post model to guarantee consistency in the data that’s saved to the database.

      Step 5 — Adding Validations and Testing the Application

      In Step 5 of How To Build a Ruby on Rails Application, you added validations to your Shark model to ensure uniformity and consistency in the data that gets saved to the sharks database. We’ll now take a similar step to ensure guarantees for the posts database as well.

      Open the file where your Post model is defined:

      Here, we want to ensure that posts are not blank and that they don’t duplicate content other users may have posted. To achieve this, add the following line to the file:

      ~/sharkapp/app/models/post.rb

      class Post < ApplicationRecord
        belongs_to :shark
        validates :body, presence: true, uniqueness: true
      end
      

      Save and close the file when you are finished editing.

      With this last change in place, you are ready to run your migrations and test the application.

      First, run your migrations:

      Next, start your server. If you’re working locally, you can do so by running:

      If you are working on a development server, run the following command instead:

      • rails s --binding=your_server_ip

      Navigate to your application’s root at http://localhost:3000 or http://your_server_ip:3000.

      The prerequisite Rails project tutorial walked you through adding and editing a Great White shark entry. If you have not added any further sharks, the application landing page will look like this:

      Shark App Landing Page

      Click on Show next to the Great White’s name. This will take you to the show view for this shark. You will see the name of the shark and its facts, and a Posts header with no content. Let’s add a post to populate this part of the form.

      Click on Add Post below the Posts header. This will bring you to the post index view, where you will have the chance to select New Post:

      Post Index View

      Thanks to the authentication mechanisms you put in place in Step 6 of How To Build a Ruby on Rails Application, you may be asked to authenticate with the username and password you created in that Step, depending on whether or not you have created a new session.

      Click on New Post, which will bring you to your post new template:

      New Post

      In the Body field, type, “These sharks are scary!”

      New Shark Post

      Click on Create Post. You will be redirected to the index view for all posts that belong to this shark:

      Post Success

      With our post resources working, we can now test our data validations to ensure that only desired data gets saved to the database.

      From the index view, click on New Post. In the Body field of the new form, try entering “These sharks are scary!” again:

      Repeat Shark Post

      Click on Create Post. You will see the following error:

      Unique Post Error

      Click on Back to return to the main posts page.

      To test our other validation, click on New Post again. Leave the post blank and click Create Post. You will see the following error:

      Blank Post Error

      With your nested resources and validations working properly, you now have a working Rails application that you can use as a starting point for further development.

      Conclusion

      With your Rails application in place, you can now work on things like styling and developing other front-end components. If you would like to learn more about routing and nested resources, the Rails documentation is a great place to start.

      To learn more about integrating front-end frameworks with your application, take a look at How To Set Up a Ruby on Rails Project with a React Frontend.



      Source link