Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

#1: Initial revision by user avatar ArtOfCode‭ · 2022-05-30T15:50:55Z (almost 2 years ago)
This is assuming that you're new to Ruby and Rails (and the MVC design pattern that comes with it), but you have programming experience. First, some orientation:

 * **Ruby** is the programming language that QPixel is written in. It's object-oriented, interpreted, and quite like Python in some ways &mdash; if any of that makes any difference to you.
 * **Bundler** is Ruby's package system. Ruby packages are called **gems**, and the **Gemfile** is a file in the root of the project that holds a list of gem dependencies. You can install all dependencies using `bundle install`.
 * **Rails** is a gem that provides a web framework for Ruby. Ruby has a number of gems that provide web frameworks; Rails is one of the most popular. It's fairly heavy-weight in terms of structure and learning curve, but it's also flexible, configurable, and well suited to larger applications.
 * **MVC** (Model-View-Controller) is the design pattern that Rails uses, which in part dictates the file structure of the project.

### File structure
Understanding the design pattern and the file structure are key to understanding how to work with the QPixel code, and they're very much linked. The root of the QPixel repository (currently) contains these directories (excluding build config):

 * `app/` contains app code: code that controls how the app works and behaves.
 * `bin/` contains binaries for various gems - you can ignore this.
 * `config/` contains Rails and environment configuration. You can usually ignore this.
 * `db/` contains database setup/change information, complex SQL-only queries, and seeds.
 * `img/` contains images for the new-user tutorial.
 * `lib/` contains library extension code. You can usually ignore this.
 * `public/` contains static content and assets.
 * `scripts/` contains Ruby scripts for various tasks (both app-called and developer utilities).
 * `test/` contains unit testing code. See [How do I write a new test case?](https://collab.codidact.org/posts/280493)

For most changes that involve app presentation or behaviour, you want the `app/` directory, which contains:

 * `assets/` contains CSS and JS
 * `controllers/` contains controller code
 * `helpers/` contains useful helper methods
 * `mailers/` contains Rails' "mailers", which handle email sending
 * `models/` contains model definitions
 * `views/` contains view HTML

### MVC
At this point you start to need a basic understanding of the MVC pattern to figure out where to go next.

 * The **Model** represents the database. There's a model file for each type of data we have, each backed by a database table. These define what fields and methods are available on each type of data. There's a model for `User`, `Post`, `AuditLog`, etc etc.
 * The **View** is what the user sees: the HTML structure for the user interface.
 * The **Controller** links the two together: every URL is handled by a controller method, which handles the incoming request, retrieves any data necessary and provides it to the view, and performs any necessary changes or operations.

-----

That should give you an idea for the overall structure of the project. Where exactly you need to go depends on what you want to do/what you're working on. For instance, if you're fixing a typo (i.e. something the user sees), you probably want a view file. If you want to change what happens (i.e. app behaviour), you probably want a controller, and/or you may need to make changes to a model to help support what you're doing.

-----

Take issue [#272](https://github.com/codidact/qpixel/issues/272) for an example. We want to add a link to each individual moderator tool page back to the moderator tools home.

In this case, we want to add a UI element. It doesn't require any additional operations to be performed or any changes to data or database structure &mdash; it's purely HTML. That means we're looking for a view file.

Moderator tool pages are handled by the `moderator` controller, so the views for them are in `app/views/moderator/`. `index.html.erb` is the home page itself, so doesn't need an extra link. To each of the other files there, we can add a link at the top.

Instead of writing the HTML ourselves (i.e. `<a href="/mod">Back to tools</a>`), we'll get Rails to do the work. We can call `link_to` to get Rails to generate an `<a>` tag; we'll use `moderator_path` to ask for the correct URL, and we can pass in any other attributes we need. Any Ruby code we want to use is enclosed in `<% %>` marks so that it gets preprocessed. Finally, we want something like this:

```ruby
<% link_to moderator_path, class: 'has-font-size-small' do %>
  &laquo; Back to moderator tools
<% end %>
```