My knowledge of Rails is pretty basic, but I have to fix a problem in a Rails project and the programmer can not be reached. So I'm trying to fix it myself, but I'm stuck.
The project revolves around user being able to add pictures to competitions, and to be able to vote on those pictures. The plan was to have to voting on the same page as the images, but this gives a few bugs in the JS and slow performance. So I want to have the voting and the overview on two different pages.
The problem is that I can't figure out how to create another page inside the views > competitions folder and link it up with the rest of the project. The easiest solution for me would be to copy the show.html.haml and paste it like votepage.html.haml but obviously that isn't so easy.
in the view > competitions folder there's an index.html.haml file, this displays a list of current competitions and gives a admin the ability to remove, add or edit certain competitions. When a user clicks on a link to a competition this gets rendered in the show.html.haml. On this page all the images that have been uploaded in that competition are shown. On that page I want a link that refers to the voting section. When a user clicks that link it should go to the votepage.html.haml (which is 100% the same as the show.html.haml but with different styling and added javascript). For now there's no need to actually make the voting work, "faking" it through front-end is good enough.
TLDR: I want to copy/paste a page in a view, but I don't know how to hook it up to the project.
Update1. I've used the console command rails generate controller competitions votepage which created a votepage for me. I could visit this one as well on http://localhost:3000/competitions/votepage
With the following code
- #competitions.each do |competition|
#container.js-masonry
.painting.item
= link_to competition do
- competition.pictures.shuffle.each do |picture|
= image_tag(picture.image_url)
I can insert images from the competitions in the page. But the problem is that I gets images from all competitions. And not so much competitions/1 , competitions/2 etc.
What you're missing is updating the routes file so that Rails knows what you want
Views:
competitions/
show.html.haml
vote.html.haml
...
Routes:
resources :competitions do
get :vote, on: :member
end
Member makes it behave like the show action, requiring a format like competitions/:id/vote
Edit:
You want to do the routes like above, but in the controller, make sure you get the competition from the id that will get passed
Controller:
def vote
#competition = Competition.find(params[:id])
end
And then instead of looping through all the competitions, you can just take the loop out and reference #competition
The basic answer is that you also need to copy the show method from app/controllers/competitions and make a votepage method with the contents in the same file.
This guide will help explain how views get wired (by the controller) to models: http://guides.rubyonrails.org/action_controller_overview.html
Related
I am working on Todo app now and I have troubles. After sign in, I am on persons profile(first controller), on it I have button for new project(projects controller-2d controller) and after pressing it, appears button for new tasks(task controller-3d controller). How I can put all of this 3 controller's views on one page. Here an example of what I mean(approximately):http://todo.kzotov.ru/
You can put anything you want in the view. You could eager load the projects and tasks and put it all on the profile page. You also don't have to map controllers and views to models, so if the PersonsController or whatever is not what you're looking for, maybe do something more specific like ProfilesController and host all this functionality there.
MVC
You'll be best reading up on the MVC programming pattern -
The bottom line is that if you send a request to your application, it will only hit one controller#action. Your multiple "controllers" should not be something to consider - you should only look at the single controller action you're accessing at that specific time.
To be more specific about this, let me detail how it all works...
OOP
Ruby (on top of which Rails is a framework), is object orientated.
This is not just a fancy phrase - it's a real pattern of programming, which allows you to focus the flow of your application around the data / objects you want to create. The objects in Rails are derived from your Models - collating & organizing the respective data for your controllers
In order to understand how Rails works - you need to appreciate that everything you do is based on objects. Your routes, actions & data all work together to provide the end-user experience we know from Rails. How that happens is down to you.
Specifically, you want to look what what you're accessing
You don't want to load multiple controllers - you want to build several models and show those. This gives you the ability to show the HTML elements / files you want:
Recommendation
I would make sure you can put all your activity on your single view, which will then mean you have to determine your controller's data in order to provide you with the data you need to show:
#app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
def index
#your index
end
end
#app/views/profile/index.html.erb
<%= link_to "task", task_path %>
What you'll probably want to do is create a separate route / method to give them the ability to pull back ajax data when the initial button was clicked. I can detail this if you need it, but what I've given you should be ample food for thought
I've been stuck on this for about 2 weeks. I need help in the proper way to do this. I have two models. Model one is Leads. Model two is Referrals.
Leads belongs_to referrals
Referrals has_many Leads
In the Lead entry screen there is a partial that displays possible Referrals for the lead to select from. There is an Add Referral link in the partial that brings up a modal using twitter bootstrap as the css framework. From that I am rendering the New action of the Referral controller.
This all works up to this point. What I want to have happen is that I can then enter a new referral, it is saved, the modal closes, and the list of referrals in the partial of the Leads edit/new view is then updated to reflect the new referral that has been added. But at this point I now have nested form_for's. As well as a Referral form that is working off a different controller.
I am not sure how I should approach this. I have been searching and trying various methods for a couple of weeks now. Do I repeat myself and completely rebuild the Referral view and controller under the Leads controller and view? Repetitive code like that is why I switched to rails, and why I feel I'm not looking at this correctly. There has to be a simple way around this. I have looked at using Gems like Draper and Cell, and I've read up on using presenters. But those seem to all be solutions for a dashboard type of view, not what I am trying to accomplish.
Any help or direction would be much appreciated.
Thank you...
This is the way i program this kind of problem.
It works for me, maybe you can adapt to your own situation.
Well, you create action on yout Referral Controller should respond with javascript.
if #referral.save
format.js
This way, you will have a create.js.erb file whitin the views folder where you keep your referral's views.
In the create.js.erb you may have something similar to this:
$('#modal_id').hide(); // Hide the modal or if you prefer, remove from DOM.
$('#referral_list_id').chidren().delete(); // Remove the list of referrals.
$('#referral_list_id').html(
"<%= escape_javascript(render('referrals_list')) %>"
); // Render a partial with the new content from your controller.
Your form for a new referral inside your modal, should be remote too:
<%= form_for #referral, :remote => true do %>
Maybe you will run into some gotchas while implementing this way, but i believe it is kinda easy to solve.
I have a very high level question that I cant find an answer to that makes sense to me. I understand it''s a terribly broad question but I'm only after some pointers in where to look for answers, not instructions on how to build my site.
So... If I want to render two different types of content in a single page using rails, how would I go about doing this? And how would I format the url? Say I create a gallery model and controller which has information about the gallery and perhaps a description, then I create a gallery-entry controller and model that belongs to the gallery which has an image and image name. If I want to create a url something like www.siteURL/galleryName/GalleryEntry that renders both the gallery info and description and all the associated gallery-entries but also a larger version of the gallery-entry that is named in the url where would i start and how would i structure this? How would i go about creating a url that has multiple attributes and how would i access them in the controller/view?
Thanks - and sorry for the vague question
There's several ways to go about it.
Your URL looks like a "vanity" URL that would exist in addition a normal RESTful route (galleries/:gallery_id/entries/:entry_id). The difference is that you don't want to show just the gallery entry.
If you want to specifically differentiate between different views of the same resource there are a number of ways it could be done, the two I'd consider first are adding another action, or adding a disambiguating query parameter. In this case, it's a hybrid, so I'd probably create a custom match and controller method.
The mapping might look like:
match ':galleryName/:entryName' => 'gallery#highlight_entry' # Or whatever
The action would be (more or less):
def highlight_entry
#gallery = Gallery.find_by_name(...)
#entries = #gallery.entries
#highlighted_entry = # pull from #entries, or retrieve
# Also, filter entries/etc. so the highlighted one doesn't show up
# etc
end
I just started deploying a Rails website. In fact, I started programming on Rails 2 days ago.
I've created a new project, added some gems, etc. Everything is working properly, and I have some basic knowledge on how all works.
The thing is that what I want to create is a simple website with some sections (let's say, News, Contact, About, Products...). All this content is kinda static.
But I came in a problem. I don't really know what to do in order to create them. What I want, for example, is something like mypage.com/products/fashionableproduct, mypage.com/about, etc, or even mypage.com/page/products.
I thought about creating a Controller, then an action for each page... afterwards, I came up with other solution: scaffolding. Creating a resource called page, that has a title, etc...
I'm really a beginner on this topic, and I would like to hear your helpful voice.
Thanks!
Check out https://github.com/thoughtbot/high_voltage for static pages for Rails.
And check out http://railscasts.com/episodes/30-pretty-page-title for setting page titles.
The paths to your files are determined by your routes. The configuration file for routes is located at config/routes.rb. You can match a URL path, and then point to a given resource. More information about routes here: http://guides.rubyonrails.org/routing.html
If you generate a controller, you can process any dynamic data and then pass this data to these "kinda static" pages. Here is an example configuration that would match the path "mypage.com/about" and display the appropriate page:
# config/routes.rb
match "/about" => "example_controller#about"
# app/controllers/example_controller.rb
class ExampleController < ApplicationController
def about
# calculations
end
end
# app/views/example/about.html.erb
<!-- This is your HTML page -->
I think the title of your post might be a bit misleading. I have the feeling you don't want static pages but some database stored content. Just like Ben Simpson tells you to do, create a normal pages controller and make it work.
In the end you might want to customize some routes to get them to be exactly the way you want as in your examples.
Since you just started the app, I strongly recommend you start over and make a new app with Rails 3.1 which is the most current version and learn how to do the basics through http://guides.rubyonrails.org/ and a few other sources such as http://railscasts.com.
You will then learn Rails the right way from the beginning. Good luck and have fun in the process.
I've created in rails(3) a new html page in my project model named contact.html.erb and I am interested in linking to it from a different page, i've added the code:
<%= link_to 'contact', contact_project_path(#project) %>
Project is a model that belongs_to a User (which is the contact in the contact page).
This link gives me an error message saying that contact_project_path doesnt exist. I know I need to define it somewhere but I don't know where or how. I want the page to be specific per project. I've created an action in the project_controler named contact and left it empty.
What am i missing?
I've searched for a soloution for quite some time and haven't found an answer to this question anywhere else. I'm aware its a little bit basic but I have no other options.
-REVISED ANSWER-
Based on comments I see you're not trying to associate a contact model, just a view. In that case, you still need to change the routes file, but you need to decide if you want to get a single contact page for all projects, or one contact view per project. IE:
# Collection Contact
example.com/projects/contact # IE One contact view for all projects
# Member Contact
example.com/projects/1/contact # IE One contact view per project
Either way you need to use a block for your project resource in your routes file. So, if you want there to be one contact page for the collection (all projects), do:
resources :projects do
collection do
get 'contact'
end
end
Or, if you want one contact view per member (one per project) do:
resources :projects do
member do
get 'contact'
end
end
Either way this will give you helper methods which you can put into link_to
For the collection it should be contact_projects_path (no arguments), and for members it should be contact_project_path(#project) (pass in the project as an argument.
You can use get post put delete or match as a parameter in a collection or member block, that just tells Rails what kind of request to handle at that URL, and what helpers to generate. For normal views you want a GET request.
I hope this finally answers your question :)
-ORIGINAL ANSWER-
This is for routing to a MODEL, not just a view
Add to your routes.rb:
resources :projects do
resource :contact
end
If I understand your question correctly, that should create a helper called project_contact_path().
This record will be projects/123/contact.
If you want more than one contact per project, you'll need to make it plural (resource :contacts). Then your records would look like projects/123/contacts/123.
See http://guides.rubyonrails.org/routing.html
You would link to this using link_to( project_contact_path(#project) ) if there's only one contact per project, or link_to( project_contact_path(#project,#contact) ) if there are multiple contacts per project.
Have a look here:
http://edgeguides.rubyonrails.org/routing.html
You should be aware that contact_project_path(#project) isn't a restful routes (unless contact_project is a model but there is little chance). You'll have to declare this name, use :as