I''m working on an app that makes use of rails'' optimistic locking feature and seeing some possibilities for improvements. It seems a bit tedious to have to add :lock_version to forms wherever the model is used. You also have to "hack" around rails'' UJS feature to add it as a URL parameter when using remote: true, method: [:put, :patch, :post, :delete]. On the controller side in rails 4 (or if you''re just using the strong_parameters gem in 3.x) you have to remember to permit the :lock_version parameter wherever you''re using that model or it will just be silently ignored rendering the protection useless. It seems like this could all be handled in rails core by introspecting the form object and injecting the lock_version as we do with the id and :method currently. I''m having problems figuring out how to address it on the UJS side. My current idea is to add a lock_with: option to link_to that works similarly to :remote, :method, :confirm, etc. Also, I can''t see any obviously clean way to handle this magically wrt strong_parameters since there is nothing inherent in strong_parameters that provides knowledge about the model that may eventually be created/updated from said parameters. Current plan there would be to create a module you can include in ActionController::StrongParameters that would automatically append :lock_version whenever permit is called. Not sure how to handle if you change the lock column name in your model though... Is this a viable approach for core or would this be better served as a gem that just monkey patches everything it needs to if they are present in the user''s app? Thanks in advance! -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
I''m not sure I understand what would be needed from the UJS side. If it''s in the form, UJS will simply pick it up and send it as a parameter. Are you saying it should be sent as a request header instead of a form parameter? -- Steve Schwartz On Monday, February 25, 2013 at 12:28 PM, Brian McManus wrote:> I''m working on an app that makes use of rails'' optimistic locking feature and seeing some possibilities for improvements. It seems a bit tedious to have to add :lock_version to forms wherever the model is used. You also have to "hack" around rails'' UJS feature to add it as a URL parameter when using remote: true, method: [:put, :patch, :post, :delete]. On the controller side in rails 4 (or if you''re just using the strong_parameters gem in 3.x) you have to remember to permit the :lock_version parameter wherever you''re using that model or it will just be silently ignored rendering the protection useless. > It seems like this could all be handled in rails core by introspecting the form object and injecting the lock_version as we do with the id and :method currently. I''m having problems figuring out how to address it on the UJS side. My current idea is to add a lock_with: option to link_to that works similarly to :remote, :method, :confirm, etc. Also, I can''t see any obviously clean way to handle this magically wrt strong_parameters since there is nothing inherent in strong_parameters that provides knowledge about the model that may eventually be created/updated from said parameters. Current plan there would be to create a module you can include in ActionController::StrongParameters that would automatically append :lock_version whenever permit is called. Not sure how to handle if you change the lock column name in your model though... > Is this a viable approach for core or would this be better served as a gem that just monkey patches everything it needs to if they are present in the user''s app? > Thanks in advance! > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com (mailto:rubyonrails-core+unsubscribe@googlegroups.com). > To post to this group, send email to rubyonrails-core@googlegroups.com (mailto:rubyonrails-core@googlegroups.com). > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
That''s right, that would not be necessary for remote: true forms. Correct me if I''m wrong but I don''t think UJS generates a form for link_to(remote: true, method: :put). It just generates an AJAX request to the server with appropriate options. There are two ways to get this working that I know of currently: 1. Use link_to with a url instead of a model object and stick the lock_version in as a param. link_to(@model, remote: true, method: :delete) becomes... link_to(model_path(@model, lock_version: @model.lock_version), remote: true, method: :delete) In this case the ajax request has the lock_version supplied as a query string parameter. In the case of a :post or :put it would be more appropriate to be part of the post/put data. 2. Use link_to with data-params specified: link_to(@model, remote: true, method: :delete) becomes... link_to(@model, remote: true, method: :delete, ''data-params'': @model.lock_version) My idea would add a simple helper option to link_to along the lines of :remote, :method, :confirm that would add the appropriate data-params for you. link_to(@model, remote: true, method: :delete, lock_with: @model) if link_to(:remote/:method) DID generate a form using the standard form_for under the covers then you''re right, this would be unnecessary and we could simply patch form_for/fields_for but I don''t think that''s the case with UJS as mentioned. On Monday, February 25, 2013 11:07:39 AM UTC-8, JangoSteve wrote:> > I''m not sure I understand what would be needed from the UJS side. If it''s > in the form, UJS will simply pick it up and send it as a parameter. Are you > saying it should be sent as a request header instead of a form parameter? > > -- Steve Schwartz > > On Monday, February 25, 2013 at 12:28 PM, Brian McManus wrote: > > I''m working on an app that makes use of rails'' optimistic locking > feature and seeing some possibilities for improvements. It seems a bit > tedious to have to add :lock_version to forms wherever the model is used. > You also have to "hack" around rails'' UJS feature to add it as a URL > parameter when using remote: true, method: [:put, :patch, :post, :delete]. > On the controller side in rails 4 (or if you''re just using the > strong_parameters gem in 3.x) you have to remember to permit the > :lock_version parameter wherever you''re using that model or it will just be > silently ignored rendering the protection useless. > > It seems like this could all be handled in rails core by introspecting the > form object and injecting the lock_version as we do with the id and :method > currently. I''m having problems figuring out how to address it on the UJS > side. My current idea is to add a lock_with: option to link_to that works > similarly to :remote, :method, :confirm, etc. Also, I can''t see any > obviously clean way to handle this magically wrt strong_parameters since > there is nothing inherent in strong_parameters that provides knowledge > about the model that may eventually be created/updated from said > parameters. Current plan there would be to create a module you can include > in ActionController::StrongParameters that would automatically append > :lock_version whenever permit is called. Not sure how to handle if you > change the lock column name in your model though... > > Is this a viable approach for core or would this be better served as a gem > that just monkey patches everything it needs to if they are present in the > user''s app? > > Thanks in advance! > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-co...@googlegroups.com <javascript:>. > To post to this group, send email to rubyonra...@googlegroups.com<javascript:> > . > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
I thought you were talking about remote forms. Correct, UJS only creates a form for links that have data-method but are not data-remote. For remote links, it just creates an ajax request with the proper method. So, e.g. `link_to(@model, method: :delete)` would turn into a form, but `link_to(@model, remote: true, method: :delete)` would not. To clarify though, you''re suggesting that rails would have a `:lock_with` option that would translate to `data-lock-with` on the link and fill it with the value of @instance.lock_version, and that UJS would just need to be aware of `data-lock-with` and append it to the parameters? If that''s the case, it''d be fairly easy to handle on the UJS side, so this would be more of a discussion on the side of the implementation in ActionView::Helpers::UrlHelper#link_to. -- Steve Schwartz On Monday, February 25, 2013 at 2:24 PM, Brian McManus wrote:> That''s right, that would not be necessary for remote: true forms. Correct me if I''m wrong but I don''t think UJS generates a form for link_to(remote: true, method: :put). It just generates an AJAX request to the server with appropriate options. > > There are two ways to get this working that I know of currently: > Use link_to with a url instead of a model object and stick the lock_version in as a param. > link_to(@model, remote: true, method: :delete) becomes... > link_to(model_path(@model, lock_version: @model.lock_version), remote: true, method: :delete) > In this case the ajax request has the lock_version supplied as a query string parameter. In the case of a :post or :put it would be more appropriate to be part of the post/put data. > Use link_to with data-params specified: > link_to(@model, remote: true, method: :delete) becomes... > link_to(@model, remote: true, method: :delete, ''data-params'': @model.lock_version) > My idea would add a simple helper option to link_to along the lines of :remote, :method, :confirm that would add the appropriate data-params for you. > > > link_to(@model, remote: true, method: :delete, lock_with: @model) > > if link_to(:remote/:method) DID generate a form using the standard form_for under the covers then you''re right, this would be unnecessary and we could simply patch form_for/fields_for but I don''t think that''s the case with UJS as mentioned. > > On Monday, February 25, 2013 11:07:39 AM UTC-8, JangoSteve wrote: > > I''m not sure I understand what would be needed from the UJS side. If it''s in the form, UJS will simply pick it up and send it as a parameter. Are you saying it should be sent as a request header instead of a form parameter? > > > > -- Steve Schwartz > > > > > > On Monday, February 25, 2013 at 12:28 PM, Brian McManus wrote: > > > > > I''m working on an app that makes use of rails'' optimistic locking feature and seeing some possibilities for improvements. It seems a bit tedious to have to add :lock_version to forms wherever the model is used. You also have to "hack" around rails'' UJS feature to add it as a URL parameter when using remote: true, method: [:put, :patch, :post, :delete]. On the controller side in rails 4 (or if you''re just using the strong_parameters gem in 3.x) you have to remember to permit the :lock_version parameter wherever you''re using that model or it will just be silently ignored rendering the protection useless. > > > It seems like this could all be handled in rails core by introspecting the form object and injecting the lock_version as we do with the id and :method currently. I''m having problems figuring out how to address it on the UJS side. My current idea is to add a lock_with: option to link_to that works similarly to :remote, :method, :confirm, etc. Also, I can''t see any obviously clean way to handle this magically wrt strong_parameters since there is nothing inherent in strong_parameters that provides knowledge about the model that may eventually be created/updated from said parameters. Current plan there would be to create a module you can include in ActionController::StrongParameters that would automatically append :lock_version whenever permit is called. Not sure how to handle if you change the lock column name in your model though... > > > Is this a viable approach for core or would this be better served as a gem that just monkey patches everything it needs to if they are present in the user''s app? > > > Thanks in advance! > > > -- > > > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > > > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com (javascript:). > > > To post to this group, send email to rubyonra...@googlegroups.com (javascript:). > > > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > > > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com (mailto:rubyonrails-core+unsubscribe@googlegroups.com). > To post to this group, send email to rubyonrails-core@googlegroups.com (mailto:rubyonrails-core@googlegroups.com). > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Sorry if I''ve been unclear. Yes, I''m suggesting a modification to link_to that would check for :lock_with options and translate that into `data-params` with locking_column=lock_column_value. I don''t think any change would actually be needed to jquery-ujs to support this. To be clear, here is a gist of what I''ve monkey patched in my current application: https://gist.github.com/bdmac/5032984 On Monday, February 25, 2013 12:21:24 PM UTC-8, JangoSteve wrote:> > I thought you were talking about remote forms. Correct, UJS only creates a > form for links that have data-method but are not data-remote. For remote > links, it just creates an ajax request with the proper method. > > So, e.g. `link_to(@model, method: :delete)` would turn into a form, but > `link_to(@model, remote: true, method: :delete)` would not. > > To clarify though, you''re suggesting that rails would have a `:lock_with` > option that would translate to `data-lock-with` on the link and fill it > with the value of @instance.lock_version, and that UJS would just need to > be aware of `data-lock-with` and append it to the parameters? > > If that''s the case, it''d be fairly easy to handle on the UJS side, so this > would be more of a discussion on the side of the implementation in > ActionView::Helpers::UrlHelper#link_to. > > -- Steve Schwartz > > On Monday, February 25, 2013 at 2:24 PM, Brian McManus wrote: > > That''s right, that would not be necessary for remote: true forms. Correct > me if I''m wrong but I don''t think UJS generates a form for link_to(remote: > true, method: :put). It just generates an AJAX request to the server with > appropriate options. > > There are two ways to get this working that I know of currently: > > 1. Use link_to with a url instead of a model object and stick the > lock_version in as a param. > link_to(@model, remote: true, method: :delete) becomes... > link_to(model_path(@model, lock_version: @model.lock_version), remote: > true, method: :delete) > In this case the ajax request has the lock_version supplied as a query > string parameter. In the case of a :post or :put it would be more > appropriate to be part of the post/put data. > 2. Use link_to with data-params specified: > link_to(@model, remote: true, method: :delete) becomes... > link_to(@model, remote: true, method: :delete, ''data-params'': > @model.lock_version) > > My idea would add a simple helper option to link_to along the lines of > :remote, :method, :confirm that would add the appropriate data-params for > you. > > link_to(@model, remote: true, method: :delete, lock_with: @model) > > if link_to(:remote/:method) DID generate a form using the standard > form_for under the covers then you''re right, this would be unnecessary and > we could simply patch form_for/fields_for but I don''t think that''s the case > with UJS as mentioned. > > On Monday, February 25, 2013 11:07:39 AM UTC-8, JangoSteve wrote: > > I''m not sure I understand what would be needed from the UJS side. If it''s > in the form, UJS will simply pick it up and send it as a parameter. Are you > saying it should be sent as a request header instead of a form parameter? > > -- Steve Schwartz > > On Monday, February 25, 2013 at 12:28 PM, Brian McManus wrote: > > I''m working on an app that makes use of rails'' optimistic locking > feature and seeing some possibilities for improvements. It seems a bit > tedious to have to add :lock_version to forms wherever the model is used. > You also have to "hack" around rails'' UJS feature to add it as a URL > parameter when using remote: true, method: [:put, :patch, :post, :delete]. > On the controller side in rails 4 (or if you''re just using the > strong_parameters gem in 3.x) you have to remember to permit the > :lock_version parameter wherever you''re using that model or it will just be > silently ignored rendering the protection useless. > > It seems like this could all be handled in rails core by introspecting the > form object and injecting the lock_version as we do with the id and :method > currently. I''m having problems figuring out how to address it on the UJS > side. My current idea is to add a lock_with: option to link_to that works > similarly to :remote, :method, :confirm, etc. Also, I can''t see any > obviously clean way to handle this magically wrt strong_parameters since > there is nothing inherent in strong_parameters that provides knowledge > about the model that may eventually be created/updated from said > parameters. Current plan there would be to create a module you can include > in ActionController::StrongParameters that would automatically append > :lock_version whenever permit is called. Not sure how to handle if you > change the lock column name in your model though... > > Is this a viable approach for core or would this be better served as a gem > that just monkey patches everything it needs to if they are present in the > user''s app? > > Thanks in advance! > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-co...@googlegroups.com. > To post to this group, send email to rubyonra...@googlegroups.com. > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-co...@googlegroups.com <javascript:>. > To post to this group, send email to rubyonra...@googlegroups.com<javascript:> > . > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
If you will allow me my 2cents :) Record locking is one of the ''not invented here'' features of most RDBMS''s and hence Rails ;) We added an abstract class which all models inherits from (instead of ActiveRecord::Base) and implemented a few "core" methods on this class (and made sure all migrations of new models contains a ''locked_by int'' field) def can_edit?(usr) # has usr permissions (with CanCan or else how) end def locked?(user_id) exec "update #{table_name} set locked_by=#{user_id} where id=#{id} and locked_by=0" end which allowed us to do this (in the controllers) def edit .. if can_edit?(current_user) && locked?(current_user) # render like any other day else # inject a flash with the error (either no edit permissions or not locked by current_user) end end def update .. params[:what_ever][:locked_by]=0 if resource.update_attributes(params[:what_ever]) .. end Currently, we are looking into the "collateral damage" (users starting to editing a record and then leaving for coffee, having a stroke or just plain drifts about in there, like it was Google search - leaving a bunch of locked records in their wake) - but hey, any solution is the offspring to a new challenge, right :) Originally we tried with optimistic locking and we did not like it at all - too many users saving data on top of each other - but then again that may just have been us implementing it the wrong way :( Like I said - just my 2cents - and probably not what you wanted <:) cheers Walther ps. the above code is part pseudo-code - part copy/paste - you''d get the drift if it suits you, and ironing the ''small-print'' out would not be a big feast :) Den 25/02/2013 kl. 18.28 skrev Brian McManus <bdmac97@gmail.com>:> I''m working on an app that makes use of rails'' optimistic locking feature and seeing some possibilities for improvements. It seems a bit tedious to have to add :lock_version to forms wherever the model is used. You also have to "hack" around rails'' UJS feature to add it as a URL parameter when using remote: true, method: [:put, :patch, :post, :delete]. On the controller side in rails 4 (or if you''re just using the strong_parameters gem in 3.x) you have to remember to permit the :lock_version parameter wherever you''re using that model or it will just be silently ignored rendering the protection useless. > > It seems like this could all be handled in rails core by introspecting the form object and injecting the lock_version as we do with the id and :method currently. I''m having problems figuring out how to address it on the UJS side. My current idea is to add a lock_with: option to link_to that works similarly to :remote, :method, :confirm, etc. Also, I can''t see any obviously clean way to handle this magically wrt strong_parameters since there is nothing inherent in strong_parameters that provides knowledge about the model that may eventually be created/updated from said parameters. Current plan there would be to create a module you can include in ActionController::StrongParameters that would automatically append :lock_version whenever permit is called. Not sure how to handle if you change the lock column name in your model though... > > Is this a viable approach for core or would this be better served as a gem that just monkey patches everything it needs to if they are present in the user''s app? > > Thanks in advance! > > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. > To post to this group, send email to rubyonrails-core@googlegroups.com. > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
On Tuesday, 26 February 2013 at 9:57 AM, Walther Diechmann wrote:> If you will allow me my 2cents :) > > Record locking is one of the ''not invented here'' features of most RDBMS''s and hence Rails ;) > > We added an abstract class which all models inherits from (instead of ActiveRecord::Base) and implemented a few "core" methods on this class (and made sure all migrations of new models contains a ''locked_by int'' field) > > def can_edit?(usr) > # has usr permissions (with CanCan or else how) > > end > > def locked?(user_id) > exec "update #{table_name} set locked_by=#{user_id} where id=#{id} and locked_by=0" > end > > which allowed us to do this (in the controllers) > > def edit > .. > if can_edit?(current_user) && locked?(current_user) > # render like any other day > else > # inject a flash with the error (either no edit permissions or not locked by current_user) > end > end > > def update > .. > params[:what_ever][:locked_by]=0 > if resource.update_attributes(params[:what_ever]) > .. > end > > Currently, we are looking into the "collateral damage" (users starting to editing a record and then leaving for coffee, having a stroke or just plain drifts about in there, like it was Google search - leaving a bunch of locked records in their wake) - but hey, any solution is the offspring to a new challenge, right :) >What you''ve implemented is pessimistic locking, which is completely different and comes with its own set of tradeoffs. If you expect conflicts to be rare, you should use optimistic locking (you''re ''optimistic'' the lock isn''t needed). If you expect them to be common, you need to lock more actively.> > Originally we tried with optimistic locking and we did not like it at all - too many users saving data on top of each other - but then again that may just have been us implementing it the wrong way :( > >This is exactly what optimistic locking is meant to prevent, users can''t save data over the top of each other if you''re using optimistic locking correctly.> > Like I said - just my 2cents - and probably not what you wanted <:) > > > cheers > Walther > > > ps. the above code is part pseudo-code - part copy/paste - you''d get the drift if it suits you, and ironing the ''small-print'' out would not be a big feast :) > > > Den 25/02/2013 kl. 18.28 skrev Brian McManus <bdmac97@gmail.com (mailto:bdmac97@gmail.com)>: > > I''m working on an app that makes use of rails'' optimistic locking feature and seeing some possibilities for improvements. It seems a bit tedious to have to add :lock_version to forms wherever the model is used. You also have to "hack" around rails'' UJS feature to add it as a URL parameter when using remote: true, method: [:put, :patch, :post, :delete]. On the controller side in rails 4 (or if you''re just using the strong_parameters gem in 3.x) you have to remember to permit the :lock_version parameter wherever you''re using that model or it will just be silently ignored rendering the protection useless. > > It seems like this could all be handled in rails core by introspecting the form object and injecting the lock_version as we do with the id and :method currently. I''m having problems figuring out how to address it on the UJS side. My current idea is to add a lock_with: option to link_to that works similarly to :remote, :method, :confirm, etc. Also, I can''t see any obviously clean way to handle this magically wrt strong_parameters since there is nothing inherent in strong_parameters that provides knowledge about the model that may eventually be created/updated from said parameters. Current plan there would be to create a module you can include in ActionController::StrongParameters that would automatically append :lock_version whenever permit is called. Not sure how to handle if you change the lock column name in your model though... > > Is this a viable approach for core or would this be better served as a gem that just monkey patches everything it needs to if they are present in the user''s app? > > Thanks in advance! > > > > -- > > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com (mailto:rubyonrails-core+unsubscribe@googlegroups.com). > > To post to this group, send email to rubyonrails-core@googlegroups.com (mailto:rubyonrails-core@googlegroups.com). > > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com (mailto:rubyonrails-core+unsubscribe@googlegroups.com). > To post to this group, send email to rubyonrails-core@googlegroups.com (mailto:rubyonrails-core@googlegroups.com). > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Yes, to be clear I''m only talking about optimistic locking here. On Monday, February 25, 2013 1:05:11 PM UTC-8, Michael Koziarski wrote:> > > On Tuesday, 26 February 2013 at 9:57 AM, Walther Diechmann wrote: > > If you will allow me my 2cents :) > > Record locking is one of the ''not invented here'' features of most RDBMS''s > and hence Rails ;) > > We added an abstract class which all models inherits from (instead of > ActiveRecord::Base) and implemented a few "core" methods on this class (and > made sure all migrations of new models contains a ''locked_by int'' field) > > def can_edit?(usr) > # has usr permissions (with CanCan or else how) > end > > def locked?(user_id) > exec "update #{table_name} set locked_by=#{user_id} where id=#{id} and > locked_by=0" > end > > which allowed us to do this (in the controllers) > > def edit > .. > if can_edit?(current_user) && locked?(current_user) > # render like any other day > else > # inject a flash with the error (either no edit permissions or not > locked by current_user) > end > end > > def update > .. > params[:what_ever][:locked_by]=0 > if resource.update_attributes(params[:what_ever]) > .. > end > > Currently, we are looking into the "collateral damage" (users starting to > editing a record and then leaving for coffee, having a stroke or just plain > drifts about in there, like it was Google search - leaving a bunch of > locked records in their wake) - but hey, any solution is the offspring to a > new challenge, right :) > > What you''ve implemented is *pessimistic* locking, which is completely > different and comes with its own set of tradeoffs. If you expect conflicts > to be rare, you should use optimistic locking (you''re ''optimistic'' the lock > isn''t needed). If you expect them to be common, you need to lock more > actively. > > > > Originally we tried with optimistic locking and we did not like it at all > - too many users saving data on top of each other - but then again that may > just have been us implementing it the wrong way :( > > This is exactly what optimistic locking is meant to prevent, users can''t > save data over the top of each other if you''re using optimistic locking > correctly. > > > Like I said - just my 2cents - and probably not what you wanted <:) > > > cheers > Walther > > > ps. the above code is part pseudo-code - part copy/paste - you''d get the > drift if it suits you, and ironing the ''small-print'' out would not be a big > feast :) > > > Den 25/02/2013 kl. 18.28 skrev Brian McManus <bdm...@gmail.com<javascript:> > >: > > I''m working on an app that makes use of rails'' optimistic locking feature > and seeing some possibilities for improvements. It seems a bit tedious to > have to add :lock_version to forms wherever the model is used. You also > have to "hack" around rails'' UJS feature to add it as a URL parameter when > using remote: true, method: [:put, :patch, :post, :delete]. On the > controller side in rails 4 (or if you''re just using the strong_parameters > gem in 3.x) you have to remember to permit the :lock_version parameter > wherever you''re using that model or it will just be silently ignored > rendering the protection useless. > > It seems like this could all be handled in rails core by introspecting the > form object and injecting the lock_version as we do with the id and :method > currently. I''m having problems figuring out how to address it on the UJS > side. My current idea is to add a lock_with: option to link_to that works > similarly to :remote, :method, :confirm, etc. Also, I can''t see any > obviously clean way to handle this magically wrt strong_parameters since > there is nothing inherent in strong_parameters that provides knowledge > about the model that may eventually be created/updated from said > parameters. Current plan there would be to create a module you can include > in ActionController::StrongParameters that would automatically append > :lock_version whenever permit is called. Not sure how to handle if you > change the lock column name in your model though... > > Is this a viable approach for core or would this be better served as a gem > that just monkey patches everything it needs to if they are present in the > user''s app? > > Thanks in advance! > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-co...@googlegroups.com <javascript:>. > To post to this group, send email to rubyonra...@googlegroups.com<javascript:> > . > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-co...@googlegroups.com <javascript:>. > To post to this group, send email to rubyonra...@googlegroups.com<javascript:> > . > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.