View file created but can't link to it - ruby-on-rails-3

I created this file: views/lendings/terms.html.erb
lendings controller works fine for the other views.
I just want to write a link from views/lendings/show to terms.html.erb view
Do i have to write an action in lendings controller just to do that?
How do I configure the routes file?
How do I create the link in show view?
<%= link_to 'read terms', lendings_terms_path %> ?
Thanks!

Yes. you need to create an action called terms inside LendingsController. If you don't need anything special in the view, then you can just leave the method empty. Then in the routes file add this:
resources :lendings do
collection do
get :terms
end
end

I tried this and it didn't work
resources :lendings do
collection do
get :terms
end
end
Then it worked with:
resources :lendings do
member do
get 'terms'
end
end
As explained in: Adding More RESTful Actions/2.10.1 Adding Member Routes.
Check: http://guides.rubyonrails.org/routing.html

Related

No route matches controller in rails app

I have an app where I'm creating a get action called "new_911". When I put new_911_call_path in the application layout I get an error "no route matches new_911 controller: calls". Yet there is an action in the calls controller called new_911. What am I doing wrong?
Calls Controller:
def new_911
#call = Call.new :call_status => "open"
respond_with #call
end
application.html.erb
<li><%= link_to 'New 911 Call', new_911_call_path %></li>
routes.rb
resources :calls do
member do
post 'close'
post 'cancel'
post 'note'
get 'new_return'
get 'duplicate_call'
get 'edit_times'
put 'update_billing'
get 'new_911'
end
rake routes:
new_911_call GET /calls/:id/new_911(.:format) calls#new_911
You need to add the parameter to the route. You're using a member route so you need to add the id parameter, take a look of this. You may need to change that route.
Figured it out. I was using a member instead of a collection. Also using new_911 gave me a constant error so I changed it to EmergencyCalls for my controller schema and utilized the normal "new" action. Added resources :emergency_calls to my routes file and it worked.
Sorry for the goof.

How to use a custom action in Rails' controller, called by a nested route

I want to add a custom action named "campaign" acting in a similar fashion like REST's "new" in the same controller, but it's purpose is different, so I wanted to separate them. Because, this campaign form will have some additional fields. One other alternative would be a passing an extra parameter to "new" action and render different templates for regular "new" action and custom "campaign". But, I wanna figure out why it didn't work out.
So, I come up with the following route ("messages" is the controller having both "new" and "campaign" actions):
get 'users/:user_id/messages/campaign', as: :campaign_user_message
or
resources :users do
resources: messages do
member do
get 'campaign'
end
end
end
At the console output, I'm getting ActiverRecord:RecordNotFound since it does this:
Started GET "/users/1/messages/campaign" for 127.0.0.1 at 2012-12-22 00:14:38 -0800
Processing by MessagesController#show as HTML
Parameters: {"user_id"=>"1", "id"=>"campaign"}
I'm calling the action in this way:
link_to campaign_user_message_path(#user)
if you want to have route such as "/users/1/messages/campaign" you should write smth like that:
resources :users do
resources :messages do
collection do
get 'campaign'
end
end
end
If you write in your way(with member do ... end) you code will generate url "/users/:user_id/messages/:id/campaign". and you should pass #user and #message:
link_to campaign_user_message_path(#user, #message)
I've did something like this overcome to the mentioned issue:
resources :users do
get 'messages/new_campaign' => 'messages#new_campaign'
post 'messages/create_campaign' => 'messages#create_campaign'
end
So, I can use the url helper "user_messages_new_campaign" to GET the action /users/:user_id/messages/new_campaign"

Rail3 | How to create standard route/action for ALL controllers?

Well, DRY! So i thought it should be easy to add a new action (like the existing new, edit) to all my controllers (in my case copy). But how do you setup a new route for ALL controllers?
Without going in to 'loops' (i.e. %w().each ...) inside the routes.rb ?
I mean, we want DRY right? So you don't want copy your action inside the routes file for each resource. I guess you should be able to extend the default actions/routes (index, new, edit,etc.) easy?
Thanks!
AFIK no way to do this by default. You could monkey-patch resources to include this functionality:
https://github.com/rails/rails/blob/b229bc70e50ec0887c5bb3aaaa9c6ee8af054026/actionpack/lib/action_dispatch/routing/mapper.rb#L982
...but my hunch is you would be better off re-considering whether this functionality can be created another way, since what you want to do is "off the Rails".
One option is create a CloneController#new that accepts a model and id and creates a clone. This seems like it would be drier, and wouldn't require you to pepper a gazillion "clone_article" "clone_blog" "clone_user" paths all over the place.
Obviously you would want to carefully white-list the models/ids that can be passed in.
Looking through the source there isn't a way to add to the default actions for a resource.
But, as #juwiley says, the methods resources :item is just a shortcut for creating a load of member and collection methods.
All you need to do is something like this
class ActionDispatch::Routing::Mapper
def resources_with_copy(*resources, &block)
block_with_copy = lambda do
block.call
member do
post :copy
end
end
resources(*resources, &block_with_copy)
end
end
Then in your routes.rb just say
resources_with_copy :items
resources_with_copy :posts do
member do
post :share
end
end
...

Ruby on rails tutorial: where is the user create view created?

Trying to follow along the ruby on rails 3 tutorial, I've completed the sign up process (through chapter 8) but nowhere has a user view: create.html.erb been created. Since 'create' is a section in the user controller, there needs to be a corresponding 'create.html.erb' file in views/users so I get a 'missing template' error when I try to use the tutorial form to create a new user.
Where does the tutorial create the create.html.erb file? I have paged through the tutorial a couple of times and can find no trace of it.
Thanks in advance for any help. --Fred
I am editing the question because for some reason the site will not let me add a comment below the responses to my question.
In UsersController... I have copied the following code directly out of the tutotrial:
def create
#user = User.new(params[:user])
if #user.save
#do something here
else
#title = "Sign up"
render = 'new'
end
end
I get: missing template users/create with {:locale=>[:en, :en].....
So if It is not a missing template issue, what is it?
create is an intermediary action, it does not require a view. in your create function make sure you do a redirect_to or a render view to something. here you can also populate a flash with messages corresponding to the success of the function (validation errors, succes for save etc)
When you create a new record, you actually call the new method, which does have an associated view called new.html.erb. The create method is called when you hit the "submit" button in the new.html.erb view, and there is no view for create - it is just a method that runs without a view.
Same applies for the update method which doesn't have it's own view, but which is "friends" with the edit action, whose associated view is called edit.html.erb.
Delete method is different

Passing a link into view

In Ruby on Rails 3 How would I create a view that decides by a parameter what link in view links to?
For example to a page in my view I pass a type parameter which displays all projects in my data base and depending on the type links to either the new show or edit action.
I am interested in only passing on the path of the link.
I would like to write something like:
<% link_to(enter_here_path) do %>
<div class="blah"><%=#project%></div>
<%end%>
You could use a conditional which returns the proper location or even creates the link, probably best wrapped in a helper method.
Something like that:
def your_link_method(type="delete")
case type
when "delete"
link_to …
when "foobar"
link_to …
else
link_to …
end
end
end
As a sidenote: This kind of construct smells IMO and I'd probably rethink my design first, before I implement a solution like this. Even if you can probably find a simpler and more elegant way to write it.