Rails: Access model from different controller - ruby-on-rails

I know this question been ask before and they said 'models are independent of the controller.' So, following my same code I did for other models I just renamed my working code to fit to my new model. But I'm getting an error undefined method 'userimages_path' Here the code I'm using.
The model is userimage and the controller is uploads.
Controller/uploads_controller.rb
def new
#userimage = Userimage.new
end
Model/userimage.rb is an empty file
Views/uploads/new.html.erb (This line is throwing the error.)
<%= form_for #userimage do |f|%>
In my routes.rb
resources :uploads
I have rake db:migrate several times to make sure I did migrate the database thinking this might be why it can't find the Userimage.
What I have I done wrong/missing here?

It is a Rails magic, when you don't specify second option(url) for form_for, Rails try to set it, in your case <%= form_for #userimage do |f|%> converts by Rails to <%= form_for #userimage, url: userimages_path do |f|%>, in your routes, there is no such _path helper.
To resolve this issue run bundle rake routes and set the right url option.
Check the documentation

try below code:
view
<%= form_for #userimage, url: "/uploads" do |f|%>
uploads controller
def create
...
end

Related

Form_for namespaced route for a resource with multiple states

I have a Blog model which has different states. In order to keep a skinny controller and follow the convention of only having CRUD operations per controller, I followed DHH's namespacing controllers pattern and namespaced out the Blog controller.
Now I have a Blogs::NewDraft controller, a Blogs::AwaitingApproval controller, and a Blogs::Active controller.
I have the following in my _form.html.erb for creating a new draft for a blog. It works for creating a new record, but it does not work for updating an existing record:
# app/views/blogs/new_drafts/_form.html.erb
<%= form_for #blog, url: :blogs_new_drafts do |f| %>
...
<% end %>
When I go to update the draft it throws this error:
No route matches [PATCH] "blogs/new_drafts"
I'm having trouble figuring out why it is saying there is a routing error when I update here because when I run rake routes it does have a route for a PATCH to blogs/new_drafts#update
Change your URL:
<%= form_for #blog, url: :blogs_new_draft(#blog) do |f| %>
...
<% end %>
The URL for your create action will differ from the update. The update action URL needs to know which blog you are trying to update.
That said, if you are trying to share _form with the new and edit views, having a single form won't work, since you are providing custom URLs which will differ between those two actions. There's ways to make it work (pass in the URL to the partial / instantiate the URL in your controller as a variable / add the form tag directly to your new/edit views / etc), but something will need to be done.

Rails: link_to only if route exists

I'm writing a Rails Engine and in one of my views I'd like to create a link to main_app if a named route exists.
I will give an example to clarify the question:
The Main application may or may not define in routes.rb:
resources :my_resource, only: :index
In my rails engine I need to add a link to my_resource_path only if main_app defined that route. I think it should be something like the following:
<%= link_to "Link", main_app.my_path if my_resource_path_exists? %>
I tried:
<%= link_to "Link", main_app.my_resource_path if
main_app.respond_to?(:my_resource_path) %>
but, when the path does not exist, that raises NoMethodError:
undefined method `my_resource_path' for #<Module>
How my_resource_path_exists? method could be implemented? I'm using ruby 2.2 and rails 4.2
The question is related to: Determine if path exists as route in Rails controller
But in this case, I have a named route (my_resource_path), so I need something slightly different, but can't figure out by myself.
I found a solution wich does not require to recover from fail. It's possible to check if the route is defined using url_helpers:
Rails.application.routes.url_helpers.method_defined?(:my_path)
So, the code could be written like that:
<%= link_to "Link", main_app.my_resource_path if
Rails.application.routes.url_helpers.method_defined?(:my_resource_path) %>
You could either use main_app.try(:my_path) or rescue NoMethodError to return false.

undefined method `pushes_path' for #<#<Class:0x007f85a15c6c90>

i'v been trying to resolve this error for the past 5 hours and I'm gonna burn my computer if I can't solve this.
undefined method `pushes_path' for #<#:0x007f859d605250> this is the error code I'm getting but i don't understand why.
this is my index.html.erb file inside of the interaction
<%= simple_form_for #push do |f| %>
<%= f.input :payload, as: :text %>
<%= f.input :segment, as: :radio_buttons %>
<%= submit_tag "start the campaign" %>
<% end %>
and this is my interaction controller
class InteractionController < ApplicationController
def index
#push =Push.new
end
end
Push is my table in the database and i'll get the inputs and write them in the database to use them for later one.
and this is my routes file
devise_for :partners
get 'home/index'
get 'segmentation/index'
get 'interaction/index'
root to: "home#index"
i really don't know why its looking for pushes_path, what am i doing wrong?
form_for
The problem you have is that your form_for method is going to try and generate a route based off your #path object. And as such, if you don't have a path created for it, you'll receive the error you're getting:
:url- The URL the form is to be submitted to. This may be represented
in the same way as values passed to url_for or link_to. So for example
you may use a named route directly. When the model is represented by a
string or symbol, as in the example above, if the :url option is not
specified, by default the form will be sent back to the current url
(We will describe below an alternative resource-oriented usage of
form_for in which the URL does not need to be specified explicitly).
The bottom line is that as Rails is object orientated, its built around the assumption that you'll have routes set up to handle the creation of individual objects.
Every time you use form_for, Rails will attempt to construct your routes from your object -- so if you're trying to do the following, it will treat the routes as photo_path etc:
#app/views/pushes/new.html.erb
<%= form_for #push do |f| %>
...
<% end %>
--
Fixes
As #mandeep suggested, there are several fixes you can employ to get this to work:
Firstly, you can just create a route for your push objects:
#config/routes.rb
resources :pushes
Secondly, as you're using a different controller, you'll want to do the following:
#config/routes.rb
resources :interactions
#app/views/pushes/new.html.erb
<%= form_for #push, url: interaction_path do |f| %>
...
<% end %>
This will route your form submission to the interactions controller, rather than the pushes controller that you'll get by default!
Objects
Something to consider when creating Rails-based backends is the object-orientated nature of the framework.
By virtue of being built on Ruby, Rails is centered on objects - a term for a variable, which basically encompasses much more than just a piece of data. Objects, in the case of Rails, are designed to give the application:
Once you understand this, the entire spectrum of Rails functionality becomes apparent. The trick is to realize that everything you do in Rails should be tied to an object. This goes for the controllers too:
--
Ever wondered why you call resources directive in your routes, for a controller? It's because you're creating a set of resourceful routes based for it:
Do you see how it's all object orientated?
This gives you the ability to define the routes for specific controllers etc. The most important thing to note is how this will give you the ability to determine which routes / controller actions your requests should go
--
There's nothing wrong in using the controller setup as you have - the most important thing is to ensure you're able to define the custom URL argument, as to accommodate the non-object based structure
In your index action you have
def index
#push =Push.new
end
and your form has
<%= simple_form_for #push do |f| %>
so your form is looking for /pushes with post verb or pushes_path and you don't have that route in your routes.rb file so to fix this you need to add this in routes.rb:
resources :pushes
Update:
when you add resources :push rails basically creates seven different routes for you. One of which is
POST /pushes pushes#create create a new push
and if you look at the html generated by your form it would be something like:
<form action="/pushes" class="new_push" id="new_push" method="post">
// your fields
</form>
notice the action and verb so when you submit your form your routes are checked for them and since you didn't define them in your routes you were getting this error
And how will i be able to use the params i m getting from this form with this new resource addition?
Your form will take you to pushes_controller create action so first of all you'll have to define them. You can access them simply by params[:pushes] in your controller action but since you want to create a new record so you'll have to permit those attributes, checkout strong parameters
If you are using rails >= 4 then you can do
class PushesController < ApplicationController
def create
#push =Push.new(push_params)
if #push.save
redirect_to #push
else
render 'interaction/index'
end
end
private
def push_params
params.require(:push).permit(:attributes)
end
end
If you are using rails < 4 then instead of permitting these attributes(because strong parameters feature came from rails 4) you'll have to tell rails that these attributes are accessible by writing this in your pushes.rb
attr_accessible :attribute_name
Why it is assuming that its pushes controller?Because of the Push.new creation?
That's because if you look at your index action #push = Push.new so #push contains a push object with nil values(as you have just initialized it) so this is where rails magic comes, rails automatically tries to figure out url of your form and since your #push is only an initialized variable so rails takes you to create action for it. For details you should checkout rails polymorphic urls If you want your form to go to interaction_controller or some other url then you'll have to specify the url option for it
<%= form_for #push, url: "your_url_for_custom_method" %>
// other fields
<% end %>
And in the end you should really read docs

Rails, Making a Rails form to save a record to an external db

Rails 2.3.5
I haven't used Rails in awhile and I'm a bit out of practice. For the application I'm working on there is an external db that's scanned by a running process and creates tickets in a ticket system. All I need to do is just save a record there.
I thought I could just connect the db and use a Rails form where I create a new model object and then a form uses that - where submitting the form should just go to a create action in the controller.
The error I'm getting from trying this has me stumped though (undefined method `tam_ticketings_path').
Thanks for any tips or help. I never had to deal with saving a record to a db outside teh application and I'm not sure exactly what I should be trying to do here (save going back to an HTML form and a manual SQL Insert statment).
Thanks!
database.yml:
tam_ticketing_db:
adapter: mysql
database: tam_ticketing_1
model: tam_ticketing
class TamTicketing < ActiveRecord::Base
TamTicketing.establish_connection "tam_ticketing_db"
set_table_name "tickets"
end
Tickets controller method:
def new_ticket
#ticket = TamTicketing.new
new_ticket view:
<% form_for(#ticket) do |f| %>
<%= f.error_messages %>
the error:
Showing app/views/tickets/new_ticket.html.erb where line #1 raised:
undefined method `tam_ticketings_path' for #<ActionView::Base:0x3b01f18>
Extracted source (around line #1):
1: <% form_for(#ticket) do |f| %>
2: <%= f.error_messages %>
3:
4: <p>
When you use form_for(someModelInstance) it will use the path method that goes to the create/update action. Make sure you have properly routed your TamTicketing model using something like this in your config/routes.rb file
resources :tam_ticketings
In Rails 2.3.5 the config/routes.rb should look like this:
map.resource :tam_ticketing
Then restart/start your server and browse your view again.
Also on your controller the proper naming for your action should just be 'new' and not 'new_tickets' inorder to have the above routing work correctly. Otherwise you need to add this:
map.new_ticket 'tam_ticketings/new_ticket', :controller => 'tam_ticketings', :action => 'new_ticket'
map.resource :tam_ticketing
I suggest making sure your controller is named TamTicketings (file name is tam_ticketings) and the action is 'new'

Making a controller exist on as a sub-controller, how to fix form routes in rails

I have a ChaptersController that does not have a direct route (i.e. site/chapters/:id) but only exists as a sub route for a BooksController (i.e. site/books/:id/chapters/:id). however, when I try to go to books/:id/chapters/new , I get the following routing error:
Showing .../app/views/chapters/_form.html.erb where line #1 raised:
No route matches {:controller=>"chapters"}
how can I fix this?
It seems like you are using nested routes in this manner:
resources :books do
resources :chapters
end
in which case you should have the named routes 'book_chapter' and 'book_chapters'. You can check this by running rake routes.
In your _form.html.erb partial you need to change this line:
<%= form_for(#chapter) do |f|%>
You need to specify the target URL of the form explicitly, and probably also handle different URLs for create and update scenarios. Try something like this:
<%= form_for(#chapter, :url => (#chapter.new_record? ? book_chapters_path(#book) : book_chapter_path(#book, #chapter) )) do |f| %>
I suppose there is wrong path in /app/views/chapters/_form.html.erb
Check what url is in tag. I suppose you forgot to change it to nested in books.
You may as well paste _form.html.erb here, so i will point it out :)

Resources