Multiple options for update action - ruby-on-rails

How can I pass and collect different options into a controller action.
E.g you have a Team model and you want to add or remove Users from the team?
I would assume this would go in the update action of the teams controller, but the update action also need to be able to update team details like name, address, ect.
I tried the following code but that produce some weird results to my css and produces errors.
link_to team_path(user), params[:add] ,:class => 'btn btn-mini pull-right', :method => :put

Weird results are probably caused by the mixed parentheses
params[:add}
what does your model look like? (Teams-Teammember relation?)
But in general:
- you should add actions to the appropriate controller (prob. teams_controller) for
adding and deleting members:
def add_member
end
def remove_member
end
and define routes in config/routes.rb to be able to use this actions (there are plenty of examples how that can be achieved in the comments generated), then you can use the resulting path helper for your link_to tag - check out the available routes and path helpers with
rake routes

Related

ActionController::UrlGenerationError using link_to

I have a controller Posts in which I have a method:
def report_user
...
end
I have a view where I would like a link that will perform some logic (it should NOT actually take the user to a different page, only perform the logic and possibly show a dialog box after completion). The logic is contained in the report_user action in the Posts controller:
<%= link_to "Report User", :controller => :Posts, :action => :report_user %>
I would ultimately like to pass some variables also to the report_user action, however I haven't gotten that far as I've come across this error:
No route matches {:action=>"report_user", :controller=>"Posts"}
message << " missing required keys: #{missing_keys.sort.inspect}" unless missing_keys.empty?
raise ActionController::UrlGenerationError, message
end
I'm not sure what the issue is. There is definitely an action in the Posts controller called report_user and it is not private. I'm not sure what the missing required keys means either. I've seen on SO other people with that error, but they all have routes defined that require parameters. I do not have any routes defined for this. Possibly I"m going about the entire thing in the wrong way?
As Nils suggested, you need an entry in routes.rb. Assuming that this is a member route using a GET request, that entry would look like this.
resources :posts do
get :report_user, on: :member
end
Next, you need to update your link to use the routing helpers that Rails provides.
<%= link_to "Report User", report_user_post_path(#post), remote: true %>
I included the remote: true option b/c you mentioned that clicking the link shouldn't reload the page. The default response for this request will be app/views/posts/report_user.js.erb.
I would encourage you to read up on Rails routing at http://guides.rubyonrails.org/routing.html.

Pass data safely from view to controller in rails

I want to pass data from a view (link) to a controller so it can look up the related information. Services for a company, in this case.
I see examples where people have added to params like this:
<div>
<%= link_to 'Services', :controller => 'company', :action => 'services', :company_id => #company.id %>
</div>
...but that results in a transparent (unsafe) URL like this:
http://localhost:5000/company/services?company_id=17
Is there a way to get around this without stuffing data into the Session? What's the best practice on links inside an app that requires authentication?
THere is no such major harm in passing data like this in View.
Still if you insist on having, then check prettyurls:
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid
Prior to we must have valid checks in controller & model files.
1. Valid Checks and redirection in Controller is helpful.
2. Depending on need adding validations in model can be a good support.
<%= link_to "Sign in", new_session_path(:id => Base64.encode64("1")) %>
and in your controller
def new
id=Base64.decode64(params[:id].to_s)
end
this is another form for create a link with data
check your routes with command un console rake routes
for more information read this documention
http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to

link_to custom action but wrong method?

all, I'm trying to get a custom action to work with a put method: in the
in _post.html.erb i have a link_to statement:
<%= link_to 'End now', post, :method => :put, :action => endnow %>
routes.rb contains:
resources :posts do
member do
put :endnow
end
and posts_controller.rb looks like:
class PostsController < ApplicationController
helper_method :endnow
[.. code for create, edit, destroy, etc ..]
def endnow
puts params
end
end
rake routes's relevant line looks like:
endnow_post PUT /posts/:id/endnow(.:format) posts#endnow
However, the action endnow helper doesn't run when clicking on this link.
Strangely, it does run with an index action (which i can tell from the puts command.
Of course, eventually the code for endnow will update #post, but for now, it just doesn't run properly.
Maybe i'm going about this the wrong way - all I'm trying to achieve is to update #post upon clicking the link to that post, and before showing it.
Any ideas / Alternatives?
Why not use the route helper method provided to you? Change your link to
<%= link_to 'End now', endnow_post_path(#post), method: :put %>
Things you're doing wrong:
If you want to specify the :action, use the Symbol for the action (you're missing a colon). :action => endnow should be action: :endnow
I will assume you have a #post instance variable you're passing from your controller to your action. You should be using that instead of post (unless you do in fact have a local post variable you're omitting from your code)
You are using endnow as an action; you should remove the helper_method :endnow line in your controller because it's not something you want to/should be accessing from your view.
This can all be avoided by using the route helper (for endnow_post you'd append _path to get the local route path: endnow_post_path), and pass in your #post as an argument.
Because you're trying to do a PUT request, you must make sure you have something like jquery-ujs included in your asset pipeline to convert these links to form submissions behind the scenes; browsers don't support PUT via the click of a link on their own.
As for why you're getting the template error when you get your link_to working, Rails is telling you that you need to create a app/views/posts/endnow.html.erb file. Your action has only puts params which does not terminate execution, leaving Rails to assume you still are trying to render some endnow.html.erb template.
Are there other ways to do what you're trying to do (change a single attribute of a specific model)? Sure. Are there better ways? That's pretty subjective; it may not be the most RESTful way, but it's arguably easier to deal with (if for example there are very specific authorization rules to check before updating the attribute you are modifying in endnow. Does the way you've started fleshing out work? Absolutely.
Finally, as a bump in the right direction, after you fix your link_to and remove the the helper_method as I have described above, your endnow action might look like this:
def endnow
post = Post.find!(params[:id])
post.some_attribute_here = some_new_value_here
post.save
redirect_to :root and return # <- this line sets a redirect back to your homepage and terminates execution, telling rails to do the redirect and **not** to render some endnow.html.erb file
end

Why is link_to with an absolute url considered technically superior to targetting controller action?

New to rails, so if this is discussed somewhere, just link me off: I had a good search but all I could find were people trying to figure out how to use link_to, not any discussion of this comment:
link_to "Profile", profile_path(#profile)
# => Profile
in place of the older more verbose, non-resource-oriented
link_to "Profile", :controller => "profiles", :action => "show", :id => #profile
# => Profile
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
I get that the latter is more verbose, and thus undesirable, but the former seems like a strange thing to be recommending.
If I have an action at say: /blah/add and I link to it using:
link_to "Link", link_add_path
Then I'm linking to mysite.com/link/add. This is a hard coded url.
If I change the route that this maps to, I have to change every instance of link_to in my code base to point to the new absolute url. This seems crazy.
However, if I link to it using:
link_to "Link", :controller => "thing", :action => "add"
Then the url is dynamically determined. If I have to change the path all I do is edit config/routes.rb and not touch any of my code. This seems like much lower maintenance.
I appreciate it's slightly more complex than that, the blah_path variable is not actually a static route, and actually contains some smarts like the application base url and prevents you from linking to urls that don't exist, but it seems like a step backwards to facilitate a fractionally less verbose syntax.
So, what's up with that?
What technical reason would you choose the former link_to syntax over the latter?
"You're doing it wrong" :P
Seriously though: use named resources, and here's why that's cool:
Example:
you've got this in your routes file:
resources :user_orders
And you are using "user_orders_path" everywhere. Then you do a refactor and decide (because the orders are now generic) that you want the controller to be called "orders" but you don't want to break all your old code. you can do this:
resources :user_orders, controller: "orders"
And your existing links will continue to work! (plus you can add a "orders" resource to move things over to the new scheme)
There's also neat things like named links:
match 'exit' => 'sessions#destroy', :as => :logout
I'd also like to add, if you needed to refactor your controller using the old link syntax - you'd still have to change a pile of controller links!
Then I'm linking to mysite.com/link/add. This is a hard coded url.
No, it's not. link_add_path is a method generated by Rails that points to a specific route in your config/routes.rb. You can see this by running
rake routes | grep link_add
If I change the route that this maps to, I have to change every instance of link_to in my code base to point to the new absolute url. This seems crazy.
No, you don't. Take the following example
get "link/add", as: :link_add, controller: :links, action: :add
If I run the above
rake routes | grep link_add
I get
link_add GET /link/add(.:format) links#add
But what if I change the name of my controller to UrisController? Just change the route in config/routes.rb
get "link/add", as: :link_add, controller: :uris, action: :add
and now you have
link_add GET /link/add(.:format) uris#add
The link_to's don't have to change because the link_add_path method is still mapped to the newly modified line in my config/routes.rb because the route name is the same. With your more explicit way of specifying controllers/actions for every link_to, you have to go through every link and update it manually to reflect the new controller: :uris controller.
Read about Naming Routes in the rails guide.

How to get a named route from a class in rails?

I have a common partial for index where i want to insert some links.
On this links i would like to use the named_routes, like
link_to "Say hi",things_path(:param1=>:hello, :params2=>:there)
but i dont know if things_path is users_path, places_path or reviews_path, because this partial is shared for all controllers. There is any way to get the named route associated to the class or the current controller.
I want something like this
link_to "Say hi", path_of(#current_class)(:param1=>:hello, :params2=>:there)
There are several approaches to this. The simplest thing is to rely on polymorphic routing, such as: link_to "Say hi", #my_object. In this case rails will look at the class of #my_object and its current state (new_record?) and use the appropriate route and restful action. Assuming your partial is named _foo.html.erb then this can be as simple as
link_to 'Say hi', foo
... which is pretty awesome. This question has been asked before, here: Polymorphic Routes in Rails - in views but I guess it's hard to find answers without knowing the magic words "polymorphic routing" :-)
A path helper like cars_path is ultimately just a shortcut to setting :controller, :action and other params like :id. If you want to make the controller always equal to the current controller you can just say
link_to "Say hi", :action => "index", :param1=>:hello, :params2=>:there
Because the :controller option is omitted, it will be assumed to be the current controller.

Resources