Rails 3.1 multiple controllers for one path - ruby-on-rails-3

We have two models, areas and stores, which we want to run off the same path: www.mysite.com/the_name_of_the_thing_here
What we would like to do is go through the areas table for a match to show the area page and, if there is no match, to go through the stores table and show the store page instead. We're not quite sure where to put this logic (in the areas controller?) and how to switch controllers. Any ideas?
Thanks

I think you can use controller action for that, something like
#area = Area.find_by_name(params[:name])
#store = Store.find_by_name(params[:name])
if #area
redirect_to area_path(#area)
elsif #store
redirect_to store_path(#store)
else
redirect_to help_url
end
If you want to change content only make other controller method in which you define variable:
#thing = Area.find_by_name(params[:name]) || Store.find_by_name(params[:name])
and pass it to view
<%= thing.name %>

Related

Using #variable within link_to in Rails

I'm trying to make
<%= link_to #company.name, current_company %>
work. It does work, as long as I stay within the same profile page. As soon as I'm trying to leave it, I get the NoMethodError in StaticPages#about - undefined method `name' for nil:NilClass. I understand the problem lies within the controller (I guess?), but that's it. Can anybody point me in the right direction please.
UPDATED
Updating methods in my satic_pages controller to
def home
#company = Company.new
end
def about
#company = Company.new
end
helps with skipping the error, but instead of the company name the links start to look like
/companies/2
Update: Since you want your link to simply display the company name, you can just do something like <%= link_to #company.name, #company%>
In your controller, you want to reference which company you're linking to, so you can do something like #company = Company.last. This would take the last record that you created. Now, when you load your page, the link should take you to the show page for that company with the last company's name as the text for the hyperlink.

Wicked Rails Gem Help Wiring Up

I want to do a multi-step form for taking in new information. One page I want to collect name/contact info, the next page I want to collect medical history, the third page demographic information.
I've installed the Wizard gem and generated a dedicated controller. All of the tutorials I've seen on it apply to devise and the signup process so I'm a little bit lost on the controller actions and the instance variables and how I should be writing them.
Was wondering if anyone has a tutorial other than a sign-up one that could maybe help me along in learning how to get this all wired up.
Any pointers or assistance is appreciated.
EDIT:
I think my problem is in the controller for my wizard.
In the show and update actions the demo shows to declare the variable of
#user = current_user
That's great, but it's a helper method that I don't need. I need to create a patient, store the patient_id in a session which I do in my create action in my main patients controller. Then somehow pass that over to the patientsteps controller.
Here's what I've tried in patientsteps
class PatientstepsController < Wicked::WizardController
before_filter :authenticate_user!
steps :medical, :summary
def show
#patient = Patient.find(params[:patient_id])
render_wizard
end
def update
#patient = Patient.find(params[:id])
#patient.attributes = params[:patient]
render_wizard #patient
end
end
When I do this, I get cannot find a patient without and ID. I understand that I'm doing this wrong, but I'm not sure how to pass in the patient_id that was created in my patients controller create action.
Patients Controller Create:
def create
#patient = Patient.new(params[:patient])
if #patient.save
session[:patient_id] = #patient.id
redirect_to patientsteps_path, notice: "Patient was successfully created."
else
render :new
end
end
In your show action, instead of params[:patient_id] you should use session[:patient_id], because the id of the patient is stored in the session, not in the params hash.
Then in the update action, you will receive the patient id in params[:patient_id], not [:id], because wicked uses params[:id] to identify which step the wizard is on.

Rails 3 - named route redirecting to wrong controller action

I'm fairly new to rails, but I have completed a couple of projects before, including the Michael Hartl Tutorial.
I'm building a simple app that stores a virtual wardrobe.
I've got 2 tables - users and items - where a user has_many items and an item belongs_to a user.
I set up the following named route in my routes.rb file:
match "/wardrobe", to: "items#index"
However, when I try to go to /wardrobe in my browser I get a no route match error as follows:
No route matches {:action=>"show", :controller=>"items"}
I'm not sure why rails is trying to route via the show action when I've named the route through the index action.
These are the relevant actions in my ItemsController:
def show
#item = Item.find(params[:id])
end
def index
#items = Item.all
end
The redirect is called on create as follows:
def create
#item = Item.new(params[:item])
if #item.save
flash[:success] = "Item added"
redirect_to wardrobe_path
else
render 'new'
end
end
rake routes provides the following:
wardrobe /wardrobe(.:format) items#index
So, I know the route exists.
Can anyone explain what's going on here? And how I can go about fixing it?
Thanks in advance
It might be because it's rake route is called wardrobe_path rather than wardrobes_path (plural) - when it's singular Rails will default to show action I believe. That might be causing the confusion.

rails 3 single table inheritance with multiple forms

I have set up a rails application that uses single table inheritance but I need to have a distinct form for my child classes. The application keeps a collection of indicators of security compromise, such as malicious IP addresses. So I have a class called Indicator which holds most of the information. However, if the indicator is a malware hash I need to collect additional information. So I created another class called MalwareIndicator which inherits from Indicator. Everything is working fine with that.
I wanted my routes to be restful and look nice so I have this in my config/routes.rb file
resources :indicators
resources :malware, :controller => "indicators", :type => "MalwareIndicator"
That works very nicely. I have all these routes that point back to my single controller. But then in the controller I'm not sure how to handle multiple forms. For example, if someone goes to malware/new the Indicators#New function is called and it is able to figure out that the user wants to create a MalwareIndicator. So what must my respond_to block look like in order to send the user to the correct form? Right now it still sends the user to the new indicator form.
def new
if params[:type] == "MalwareIndicator"
#indicator = MalwareIndicator.new
else
#indicator = Indicator.new
end
#pagename = "New Indicator(s)"
respond_to do |format|
format.html # new.html.erb
format.json { render json: #indicator }
end
end
I feel like I'm pretty close. On the other hand, I might be doing everything wrong so if anyone wants to slap me and say "quit being a dumbass" I would be grateful for that as well.
I usually try to avoid STI because there are only troubles with that (image third indcator with different attributes and fourth and fifth with more fields and before you realize you end up with huge table where most columns are unused). To answer your question: you can create different new views for different classes and respond like that:
respond_to do |format|
format.html { render action: "new_#{#indicator.class.to_s.underscore}" }
format.json { render json: #indicator }
end
that should render new_indicator.html.erb or new_malware_indicator.html.erb depends on #indicator class.
I handled it in the view itself. The route entry for malware causes the controller to receive a type parameter and the controller uses that to create an instance of the correct class. In the new.html.erb file I put this at the end:
<%= render :partial => #indicator.class.to_s.downcase %>
So if a MalwareIndicator was created by the controller then #indicator.class.to_s.downcase will return malwareindicator. I have a partial file called _malwareindicator.html.erb which has the correct form in it.
So if I have to create another descendant of the Indicator class I can add another resources entry to the routes file and create a partial called _whateverindicator.html.erb and it should work out OK.

Rails if referrer then do issue

I am trying to figure out the best way to build an if else if statement in the controller around a rails specific referrer. Is there a way to pull the last rails path and use it in the below statement? I think I am close but totally stumped...
This is an update action that will be hit from one form at multiple locations on the site.
I am looking to replace "form_path"
def update
#object = Milestone.find(params[:id])
if #milestone.update_attributes(params[:milestone])
if request.referer == form_path
redirect_to root_path
else
redirect_to object2_path
end
else
....
end
end
Is form_path a variable you're defining somewhere else in the controller? Outside of understanding that, it looks like it should work.
Instead of messing with referer, you could place a hidden_field in the form based on where it's coming from, and pull that out of the params hash.
Something like:
hidden_field_tag :location, controller_name
Then in the controller:
if params[:location] == yadda yadda