Rails 3 Routing Error (Namespaced routes help) - ruby-on-rails

Model relationships:
class Project < ActiveRecord::Base
...
has_one :project_team
...
end
class ProjectTeam < ActiveRecord::Base
belongs_to :project
end
Controller:
class Project::TeamController < ApplicationController
...
end
Routes:
resources :projects do
namespace :project do
resources :team
end
end
Form code:
= form_for #project do |f|
When I visit the new Project form, I get the following error:
No route matches {:controller=>"project/team", :project_id=>#<Project id: nil, user_id: 1 ...
I've tried many variations of this:
= form_for [:project, :team, #project] do |f|
To no avail. The routes are just barely off. But, I'm on the new project form, so I'm wondering why it's trying to grab the project team for that anyway.
Thanks for the help! [:

We should use the nested resources here,
resources :projects do
resource :project_team
end

I'm not sure of the issue, but to fix it, I just pluralized my controller name.

Related

How to create form for nested resource with has_many through association?

I'm having trouble creating the correct form_with syntax to create a record for a has_many through association and cannot find an example to copy.
My model has a Factory. Factories can have Equipment. Equipment can have many EquipmentVariations. Variations are specific to a particular type of equipment, but are different for each specific piece of equipment (so the VariationType is associated with the EquipmentType)
I can create the factory (e.g. localhost/factories/1)
I can create the equipment at the factory (e.g. localhost/factories/1/equipment/1)
But I cannot manage to make a form that creates EquipmentVariations. That is, when I navigate to localhost/factories/1/equipment/1 I want a form to add EquipmentVariations to that Equipment entry.
Here's my code:
routes.rb
resources :factories do
resources :equipment do
resources :equipment_variations
end
end
resources :equipment_types do
resources :variation_types
end
Models
class Factory < ApplicationRecord
has_many :equipment
end
class Equipment < ApplicationRecord
belongs_to :factory
belongs_to :equipment_type
has_many :equipment_variations
has_many :variation_types, through: :equipment_variations
end
class EquipmentVariation < ApplicationRecord
belongs_to :equipment
belongs_to :variation_type
end
class VariationType < ApplicationRecord
belongs_to :equipment_type
has_many :equipment_variations
has_many :equipment, through: :equipment_variations
end
And the view in app/views/equipment/show.html.erb
<h1><%= #equipment.equipment_type.name %></h1>
<h3>Add Variation</h3>
<%= form_with(model: [#equipment, VariationType.new], url: factory_equipment_equipment_variations_path, local: true) do |form| %>
<%= form.submit %>
<% end %>
This is as close as I have been able to manage, but gives the error: No route matches {:action=>"index", :controller=>"equipment_variations", :factory_id=>"2", :id=>"3"}, missing required keys: [:equipment_id]
Basically, I need to be able to post to the URL /factories/1/equipment/1/equipment_variations from the page at /factories/1/equipment/1. The route given for that is factory_equipment_equipment_variations which is why I specified that in the url parameter, but I feel there must be a simpler way to acheive this. What should the form_with parameters look like?
Ok, so I figured this out. I was close, but the correct syntax is as follows
<%= form_with(model: [#factory, #equipment, EquipmentVariation.new], local: true) do |form| %>
So you need to give the model: parameter all the models for the route (factory, equipment) and it will figure out the correct path by itself and submit the parameters appropriately.
Also, my controller for EquipmentVariation called by above looks like:
def create
#equipment = Equipment.find(params[:equipment_id])
#equipment.variation_types << VariationType.find(params[:variation_type][:variation_type_id])
end
Hope this helps someone in future!

rails- Pass infomation to a controller based on url

I have a controller for "Productions" and if you go to localhost/productions you see an index page, you can click show and view the show page for that particular productions.
Each production has a unique ID like 036ea872f9011a7c, I want my users to be able to add items to a production like follows:
localhost/productions/036ea872f9011a7c/fixtures/add
localhost/productions/036ea872f9011a7c/positions/add
localhost/productions/036ea872f9011a7c/dimmers/add
localhost/productions/036ea872f9011a7c/channels/add
localhost/productions/036ea872f9011a7c/etc/add
You should build a route with the necessary parameters like this:
Suppose we have tasks that we assign to a project
model project.rb:
class Project < ActiveRecord::Base
has_many :tasks, through: :project_task
end
model task.rb
class Task < ActiveRecord::Base
has_many :projects, through: :project_task
end
routes.rb
...
resources :projects do
member do
get 'affect_task/:task_id', action: 'affect_task', as: :affect_task
end
end
projects/show.haml
= link_to "task_name", affect_task_project_path(task_id: #task_id, project_id: #project_id)
controller.rb
...
def affect_task
...
CollaboratorTask.create(task_id: params[:task_id], project_id: params[:project_id])
...
end
...
Of course this is an example so you understand..

Rails Polymorphic associations without nesting forms

I am still new to rails and I am trying to figure out how to implement a polymorphic association without using a nested route or form. I tried searching but everything seemed to be about nesting forms or adding comments, which is not what I am trying to do.
Here are my models
Article.rb
class Article < ActiveRecord::Base
belongs_to :articable, polymorphic: true
end
Organization.rb
class Organization < ActiveRecord::Base
has_many :articles, as: :articable
end
People.rb
class People < ActiveRecord::Base
has_many :articles, as: :articable
end
I want to implement a 'New Article' link from a Organization or People show page and have the correct article_id and article_type entered. What would the correct syntax be to generate this link?
Thanks!
Routes:
resource :people do
resource :articles
end
resource :organizations do
resource :articles
end
ArticlesController:
def create
article = Article.new(params[:article])
if params[:people_id]
people = People.find(params[:people_id])
people.articles << article
else
organization = Organization.find(params[:organization_id])
organization.articles << article
end
article.save
end
Organizations view:
link_to new_organization_article_path(#organization)...

one-to-one relation in Rails

I'm trying to achieve a simple 1 to 1 relation in Rails 3 where a user can connect a bank account.
class User < ActiveRecord::Base
has_one :bank
accepts_nested_attributes_for :bank
attr_accessible :bank_attributes
end
class Bank < ActiveRecord::Base
belongs_to :user
end
Route
resources :users do
resources :bank
Now when i build a new bank object for a user in users/1/bank/new like this:
def new
#user = User.find(current_user.id)
#bank = #user.build_bank
end
I get an error on my for which looks like this:
<%= simple_form_for(#bank) do |f| %>
The error is:
undefined method `banks_path' for #<#<Class:0x007fa7bd090f08>:0x007fa7c0545b40>
My goal is to have a separate form for a user to add there bank account information.. Hope someone can help me in the right direction to do this. I also use ActiveAdmin and the relation with forms etc works fine there.
Any help is appreciated!
Since bank is nested under user, you need to give the user to the form:
<%= simple_form_for([#user, #bank]) do |f| %>
In addition, your routes file should be
resources :users do
resource :bank
This will give you a user_bank_path for a user
You need to declare resource in plural form regardless of the association type.
So, your resource declaration
resources :users do
resource :banks
end

Rails 3 namespaced model and controller routing issue

I have namespaced model Equipment::Feature and namespaced controller in my admin part Admin::Equipment::FeaturesController. Model is generic and is used as from within :admin namespace and for public website. I've set up the routing for :admin and :equipment namespaces
namespace :admin do
namespace :equipment do
resources :features
end
end
Which gives me following routes:
admin_equipment_features GET /admin/equipment/features(.:format) admin/equipment/features#index
POST /admin/equipment/features(.:format) admin/equipment/features#create
new_admin_equipment_feature GET /admin/equipment/features/new(.:format) admin/equipment/features#new
edit_admin_equipment_feature GET /admin/equipment/features/:id/edit(.:format) admin/equipment/features#edit
admin_equipment_feature GET /admin/equipment/features/:id(.:format) admin/equipment/features#show
PUT /admin/equipment/features/:id(.:format) admin/equipment/features#update
DELETE /admin/equipment/features/:id(.:format) admin/equipment/features#destroy
Pretty standard stuff. But when I address /admin/equipment/features it throws uninitialized constant Admin::Equipment::FeaturesController::Equipment exception
#index action in my Admin::Equipment::FeaturesController looks like
def index
#features = Equipment::Feature.all
end
It did seem to work, until I declared Admin::Equipment namespace. Before it was like Admin::EquipmentFeaturesController
I guess this is some sort of namespace collision, but I don't get it - where does it come from?
Thanks in advance!
UPDATE Feature model (uses STI pattern)
class Equipment::Feature < ActiveRecord::Base
attr_accessible :category_id, :name_en, :name_ru, :type
belongs_to :category, :class_name => 'Equipment::Category'
has_many :item_features, :class_name => 'Equipment::ItemFeature'
has_many :items, :through => :item_features
translates :name
end
class FeatureBoolean < Equipment::Feature
end
class FeatureNumeric < Equipment::Feature
end
class FeatureString < Equipment::Feature
end
class FeatureRange < Equipment::Feature
end
UPDATE2
Fixing #index action as per answer below resolved the issue. New code:
def index
#features = ::Equipment::Feature.all
end
I think it's now looking for Feature in Admin::Equipment, rather than in ::Equipment
Try specifying that there is no namespace, i.e.
def index
#features = ::Equipment::Feature.all
end
Please create folder like this app/controllers/admin/equipment/features.rb
And then edit your controller name to Admin::Equipment::FeaturesController
class Admin::Equipment::FeaturesController < ActiveRecord::Base
end

Resources